Compare commits

...

54 Commits

Author SHA1 Message Date
hvolmer
cd15b4e93b Merge pull request #49 from PepperDash/feature/add-new-tx-features-to-other-tx-models
Feature/add new tx features to other tx models
2020-02-26 16:24:39 -07:00
Neil Dorin
92b6e8a752 Merge branch 'release/v1.4.33' into feature/add-new-tx-features-to-other-tx-models 2020-02-26 16:19:33 -07:00
Neil Dorin
d905b2c25b Merge pull request #48 from PepperDash/bugfix/ecs-1255
Bugfix/ecs 1255
2020-02-25 10:13:25 -07:00
Neil Dorin
943ae2115b Closes #33 2020-02-24 16:12:58 -07:00
Neil Dorin
7be1c6df44 Updates to PD.Core v1.0.34 2020-02-24 16:09:58 -07:00
Neil Dorin
bea94ceaf0 Fixes incorrect spelling of Extensions 2020-02-24 16:07:38 -07:00
Neil Dorin
9b6b661c18 Merge remote-tracking branch 'origin/master' into bugfix/ecs-1255 2020-02-24 16:01:36 -07:00
Neil Dorin
cdab417de8 Merge branch 'development' into bugfix/ecs-1255 2020-02-24 16:01:18 -07:00
Neil Dorin
d80602d3c6 Adds IHasFreeRun and IVgaBrightnessContrastControls to 401 and 302 Tx controller classes 2020-02-24 14:11:18 -07:00
Neil Dorin
a1e9d35a69 Implements IHasFreeRun and IHasVgaBrightnessContrastControls on DMTx200Controller 2020-02-24 12:21:52 -07:00
Nick Genovese
fd84e44a85 Merge pull request #45 from PepperDash/ndorin-issue-templates
Update issue templates
2020-02-21 20:05:45 -05:00
Neil Dorin
4be32cb909 Update issue templates 2020-02-21 16:31:52 -07:00
Andrew Welker
b48b9ad9cf Merge pull request #44 from PepperDash/feature/dm-disable-free-run
Feature/dm disable free run
2020-02-21 09:28:50 -07:00
Neil Dorin
b7f97dc146 Adds new joins to DmTxControllerJoinMap and associated bridge 2020-02-20 15:32:49 -07:00
Andrew Welker
c8eb4923e6 Merge pull request #42 from PepperDash/ndorin-add-contributing
Create CONTRIBUTING.md
2020-02-19 12:44:39 -07:00
Neil Dorin
ddeb41832f Update CONTRIBUTING.md
Fixes spelling and grammar errors pointed out by @minesguy82
2020-02-19 12:41:48 -07:00
Neil Dorin
c62508b8ae Create CONTRIBUTING.md 2020-02-19 10:41:42 -07:00
Neil Dorin
e894e2d1b4 Adds IVgaBrightnessContrastControls to DmTx201XController 2020-02-18 20:46:42 -07:00
Neil Dorin
3e16cbb092 Adds VGA brightness and contrast feedback/control to DM-TX-201-C 2020-02-18 20:45:01 -07:00
Neil Dorin
73ab16ce55 Adds FreeRun support for DM-TX-201-C. Need to test on NYC hardware and then apply to other TX classes. 2020-02-18 20:09:51 -07:00
hvolmer
f74d2241a0 Merge pull request #27 from PepperDash/hotfix/sgd-failover-to-embedded-resources
Fix SGD issue
2020-02-18 16:55:25 -07:00
hvolmer
65b95006be Merge pull request #39 from PepperDash/hotfix/sgd-failover-to-embedded-resources
Closes #26.  If specified SGD file isnt' found in User/sgd directory,…
2020-02-18 16:51:40 -07:00
hvolmer
c871f5e6c8 Merge pull request #40 from PepperDash/maintenance/update-pd-core-1.0.33
Maintenance/update pd core 1.0.33
2020-02-18 16:50:38 -07:00
Neil Dorin
66b08b6be0 Merge branch 'bugfix/ecs-1260' into maintenance/update-pd-core-1.0.33 2020-02-18 16:22:31 -07:00
Neil Dorin
0228d2938d Updates PepperDash.Core to 1.0.33 2020-02-18 16:22:11 -07:00
Neil Dorin
d2fc4d2175 Merge remote-tracking branch 'origin/development' into bugfix/ecs-1260 2020-02-18 15:52:11 -07:00
Neil Dorin
5f4793ed0c Merge pull request #32 from bitm0de/master
Code fixes and plugin system types added
2020-02-18 12:29:26 -07:00
bitm0de
f33f42a40e Fixed misspelling 2020-02-15 19:51:09 -07:00
bitm0de
86dcd066fe Added MinimumEssentialsFrameworkVersion to plugin interface 2020-02-15 15:10:22 -07:00
bitm0de
c420e06540 Fixed conditional check to prevent NullReferenceException 2020-02-15 14:43:31 -07:00
bitm0de
00e14b746b Added floating point epsilon comparison for equality check 2020-02-15 14:32:46 -07:00
bitm0de
ee26e77f15 Added plugin entrypoint attribute and interface 2020-02-15 14:28:41 -07:00
bitm0de
8a09ffa7e4 Updated to HDCPSupportOnFeedback from obsolete HDPCSupportOnFeedback 2020-02-15 14:28:10 -07:00
Neil Dorin
4d300a9b68 Closes #26. If specified SGD file isnt' found in User/sgd directory, we look in application/SGD directory for embedded resource file. Updates PD.Core to latest. 2020-02-14 14:28:40 -07:00
Neil Dorin
dc9eee9325 Update Readme.md
Fix typo
2020-02-13 20:31:06 -07:00
Neil Dorin
f5586d2c9d Merge pull request #22 from PepperDash/feature/add-example-configs
Feature/add example configs
2020-02-13 19:28:46 -07:00
hvolmer
28d5daab5b Merge pull request #12 from PepperDash/feature/add-example-configs
Feature/add example configs
2020-02-13 09:43:55 -07:00
hvolmer
1a80bcf5c2 Merge pull request #14 from PepperDash/ndorin-patch-1
Updates Readme.md
2020-02-13 09:41:33 -07:00
Neil Dorin
e5d745f508 Updates Readme.md
Adds working links and links to existing wiki pages to prevent redundant information
2020-02-13 00:04:55 -07:00
Neil Dorin
f1278d0ee4 Adds debug statement to Hardware_OnlineStatusChange callback to help figure out issues with devices not reporting online status correctly. Removes IsRegistered from Feedbacks and fires update manually. 2020-02-12 16:07:43 -07:00
Neil Dorin
56fae89ae2 Merge branch 'master' into bugfix/ecs-1260 2020-02-12 10:46:50 -07:00
Trevor Payne
48cc8ec33f ECS-1258 : Fixed Issue related to improper bridging of c2nrths and statusSign. ECS-1248 : FIxed issues related to duplucate joins on GLSODTCCN ECS-1252 : Fixed Missing Feedbacks in c2nrths and StatusSign 2020-02-11 18:49:43 -06:00
Neil Dorin
69724a8d4d Merge remote-tracking branch 'origin/development' into bugfix/ecs-1255 2020-02-03 14:27:58 -07:00
Neil Dorin
3648bdcae4 fixed ECS-1255 by checking for inputSlotSupportsHdcp2 config value on each input card and defaulting to false if not defined in config. 2020-02-03 14:27:28 -07:00
Trevor Payne
d2b8d38000 Merge branch 'bugfix/ecs-1252' into local/BuildBetaBaml 2020-01-31 11:18:33 -06:00
Trevor Payne
48da139b2f ECS - 1252 Merge branch - Fixed missing feedbacks in BridgeControllers for StatusSign and C2nRts. Added Name feedbacks for same. 2020-01-31 11:13:31 -06:00
Trevor Payne
32a548b8fb ECS-1252 Fixed missing feedbacks in BridgeControllers for StatusSign and C2nRts. Added Name feedbacks for same. 2020-01-31 11:11:47 -06:00
Trevor Payne
0724ec06eb ecs-1252 Fixed missing feedbacks in BridgeControllers for StatusSign and C2nRts. Added Name feedbacks for same. 2020-01-31 11:08:44 -06:00
Trevor Payne
df6bd2a21f ECS-1248 Duplicate join map entry 'DisablePir' - removed and shifted map up by one 2020-01-27 11:02:15 -06:00
Trevor Payne
8d3b409ec3 Merge branch 'feature/ecs-1245' into feature/ecs-1247
Require features from ECS-1245 to be in my beta build for final testing of this branch.
2020-01-27 10:12:58 -06:00
Trevor Payne
9eb48acd6a Added Raw states for PIR and US sensors on the GlsOdtOccupancySensorController and corresponding joinMap data and Bridge connections 2020-01-27 10:00:48 -06:00
Andrew Welker
4361fe6186 Merge branch 'development' of https://bitbucket.org/Pepperdash_Products/essentials into feature/ecs-1245 2020-01-23 13:06:29 -07:00
Andrew Welker
09bc84346d ECS-1245 Added C2nRths Controller and Bridge 2020-01-23 13:02:42 -07:00
Andrew Welker
8f530aa7fe ECS-1244 Added StatusSignController Class and bridge 2020-01-23 12:33:28 -07:00
39 changed files with 1578 additions and 576 deletions

34
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,34 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]-"
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Stacktrace**
Include a stack trace of the exception if possible.
```
Paste stack trace here
```
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,21 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]-"
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
If this is a request for support for a new device or type, be as specific as possible and include any pertinent manufacturer and model information.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

110
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,110 @@
# Contributors Guide
Essentials is an open source project. If you are interested in making it better,
there are many ways you can contribute. For example, you can:
- Submit a bug report
- Suggest a new feature
- Provide feedback by commenting on feature requests/proposals
- Propose a patch by submitting a pull request
- Suggest or submit documentation improvements
- Review outstanding pull requests
- Answer questions from other users
- Share the software with other users who are interested
- Teach others to use the software
## Bugs and Feature Requests
If you believe that you have found a bug or wish to propose a new feature,
please first search the existing [issues] to see if it has already been
reported. If you are unable to find an existing issue, consider using one of
the provided templates to create a new issue and provide as many details as you
can to assist in reproducing the bug or explaining your proposed feature.
## Patch Submission tips
Patches should be submitted in the form of Pull Requests to the Essentials
[repository] on GitHub. But first, consider the following tips to ensure a
smooth process when submitting a patch:
- Ensure that the patch compiles and does not break any build-time tests.
- Be understanding, patient, and friendly; developers may need time to review
your submissions before they can take action or respond. This does not mean
your contribution is not valued. If your contribution has not received a
response in a reasonable time, consider commenting with a polite inquiry for
an update.
- Limit your patches to the smallest reasonable change to achieve your intended
goal. For example, do not make unnecessary indentation changes; but don't go
out of your way to make the patch so minimal that it isn't easy to read,
either. Consider the reviewer's perspective.
- Before submission, please squash your commits to using a message that starts
with the issue number and a description of the changes.
- Isolate multiple patches from each other. If you wish to make several
independent patches, do so in separate, smaller pull requests that can be
reviewed more easily.
- Be prepared to answer questions from reviewers. They may have further
questions before accepting your patch, and may even propose changes. Please
accept this feedback constructively, and not as a rejection of your proposed
change.
## GitFlow Branch Model
This repository adheres to the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branch model and is intitialized for GitFlow to make for consistent branch name prefixes. Please take time to familiarize yourself with this model.
- `master` will contain the latest stable version of the framework and release builds will be created from tagged commits on `master`.
- HotFix/Patch Pull Requests should target `master` as the base branch.
- All other Pull Requests (bug fixes, enhancements, etc.) should target `development` as the base branch.
- `release/vX.Y.X` branches will be used for release candidates when moving new features from `development` to `master`.
Beta builds will be created from tagged commits on release candidate branches.
## Review
- We welcome code reviews from anyone. A committer is required to formally
accept and merge the changes.
- Reviewers will be looking for things like threading issues, performance
implications, API design, duplication of existing functionality, readability
and code style, avoidance of bloat (scope-creep), etc.
- Reviewers will likely ask questions to better understand your change.
- Reviewers will make comments about changes to your patch:
- MUST means that the change is required
- SHOULD means that the change is suggested, further discussion on the
subject may be required
- COULD means that the change is optional
## Timeline and Managing Expectations
As we continue to engage contributors and learn best practices for running a successful open source project, our processes
and guidance will likely evolve. We will try to communicate expectations as we are able and to always be responsive. We
hope that the community will share their suggestions for improving this engagement. Based on the level of initial interest
we receive and the availability of resources to evaluate contributions, we anticipate the following:
- We will initially prioritize pull requests that include small bug fixes and code that addresses potential vulnerabilities
as well as pull requests that include improvements for processor language specifications because these require a
reasonable amount of effort to evaluate and will help us exercise and revise our process for accepting contributions. In
other words, we are going to start small in order to work out the kinks first.
- We are committed to maintaining the integrity and security of our code base. In addition to the careful review the
maintainers will give to code contributions to make sure they do not introduce new bugs or vulnerabilities, we will be
trying to identify best practices to incorporate with our open source project so that contributors can have more control
over whether their contributions are accepted. These might include things like style guides and requirements for tests and
documentation to accompany some code contributions. As a result, it may take a long time for some contributions to be
accepted. This does not mean we are ignoring them.
- We are committed to integrating this GitHub project with our team's regular development work flow so that the open source
project remains dynamic and relevant. This may affect our responsiveness and ability to accept pull requests
quickly. This does not mean we are ignoring them.
- Not all innovative ideas need to be accepted as pull requests into this GitHub project to be valuable to the community.
There may be times when we recommend that you just share your code for some enhancement to Ghidra from your own
repository. As we identify and recognize extensions that are of general interest to the reverse engineering community, we
may seek to incorporate them with our baseline.
## Legal
Consistent with Section D.6. of the GitHub Terms of Service as of 2019, and the MIT license, the project maintainer for this project accepts contributions using the inbound=outbound model.
When you submit a pull request to this repository (inbound), you are agreeing to license your contribution under the same terms as specified in [LICENSE] (outbound).
This is an open source project.
Contributions you make to this repository are completely voluntary.
When you submit an issue, bug report, question, enhancement, pull request, etc., you are offering your contribution without expectation of payment, you expressly waive any future pay claims against PepperDash related to your contribution, and you acknowledge that this does not create an obligation on the part of PepperDash of any kind.
Furthermore, your contributing to this project does not create an employer-employee relationship between the PepperDash and the contributor.
[issues]: https://github.com/PepperDash/Essentials/issues
[repository]: https://github.com/PepperDash/Essentials
[LICENSE]: https://github.com/PepperDash/Essentials/blob/master/LICENSE.md

View File

@@ -166,6 +166,16 @@ namespace PepperDash.Essentials.Bridges
(device as PepperDash.Essentials.Devices.Common.Occupancy.GlsOccupancySensorBaseController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is StatusSignController)
{
(device as StatusSignController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
else if (device is C2nRthsController)
{
(device as C2nRthsController).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
continue;
}
}
}

View File

@@ -0,0 +1,38 @@
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Bridges
{
public static class C2nRthsControllerApiExtensions
{
public static void LinkToApi(this C2nRthsController device, BasicTriList triList, uint joinStart,
string joinMapKey)
{
var joinMap = new C2nRthsControllerJoinMap();
var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<C2nRthsControllerJoinMap>(joinMapSerialized);
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, device, "Linking to Trilist '{0}'", triList.ID.ToString("X"));
triList.SetBoolSigAction(joinMap.TemperatureFormat, device.SetTemperatureFormat);
device.IsOnline.LinkInputSig(triList.BooleanInput[joinMap.IsOnline]);
device.TemperatureFeedback.LinkInputSig(triList.UShortInput[joinMap.Temperature]);
device.HumidityFeedback.LinkInputSig(triList.UShortInput[joinMap.Humidity]);
triList.StringInput[joinMap.Name].StringValue = device.Name;
}
}
}

View File

@@ -16,7 +16,7 @@ using Newtonsoft.Json;
namespace PepperDash.Essentials.Bridges
{
public static class DmChassisControllerApiExtentions
public static class DmChassisControllerApiExtensions
{
public static void LinkToApi(this DmChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey)
{
@@ -81,14 +81,14 @@ namespace PepperDash.Essentials.Bridges
}
}
if (basicTxDevice != null && advancedTxDevice == null)
trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true;
if (advancedTxDevice != null)
if (advancedTxDevice != null) // Advanced TX device
{
advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
// Flag if the TX is an advanced endpoint type
trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true;
}
else if(advancedTxDevice == null || basicTxDevice != null)
else if(advancedTxDevice == null || basicTxDevice != null) // Basic TX device
{
Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot);
dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);

View File

@@ -57,7 +57,7 @@ namespace PepperDash.Essentials.Bridges
trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability;
if(txR.InputPorts[DmPortName.HdmiIn] != null)
if (txR.InputPorts[DmPortName.HdmiIn] != null)
{
var inputPort = txR.InputPorts[DmPortName.HdmiIn];
@@ -71,7 +71,7 @@ namespace PepperDash.Essentials.Bridges
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
}
}
if (txR.InputPorts[DmPortName.HdmiIn1] != null)
{
var inputPort = txR.InputPorts[DmPortName.HdmiIn1];
@@ -103,6 +103,22 @@ namespace PepperDash.Essentials.Bridges
}
}
var txFreeRun = tx as IHasFreeRun;
if (txFreeRun != null)
{
txFreeRun.FreeRunEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FreeRunEnabled]);
trilist.SetBoolSigAction(joinMap.FreeRunEnabled, new Action<bool>(b => txFreeRun.SetFreeRunEnabled(b)));
}
var txVga = tx as IVgaBrightnessContrastControls;
{
txVga.VgaBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaBrightness]);
txVga.VgaContrastFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaContrast]);
trilist.SetUShortSigAction(joinMap.VgaBrightness, new Action<ushort>(u => txVga.SetVgaBrightness(u)));
trilist.SetUShortSigAction(joinMap.VgaContrast, new Action<ushort>(u => txVga.SetVgaContrast(u)));
}
}
static void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)

View File

@@ -1,110 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Devices.Common.Occupancy;
using PepperDash.Essentials.Core;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Bridges
{
public static class GlsOccupancySensorBaseControllerApiExtensions
{
public static void LinkToApi(this GlsOccupancySensorBaseController occController, BasicTriList trilist, uint joinStart, string joinMapKey)
{
GlsOccupancySensorBaseJoinMap joinMap = new GlsOccupancySensorBaseJoinMap();
var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
#region Single and Dual Sensor Stuff
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
// Occupied status
trilist.SetSigTrueAction(joinMap.ForceOccupied, new Action(() => occController.ForceOccupied()));
trilist.SetSigTrueAction(joinMap.ForceVacant, new Action(() => occController.ForceVacant()));
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback]);
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback]);
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback]);
// Timouts
trilist.SetUShortSigAction(joinMap.Timeout, new Action<ushort>((u) => occController.SetRemoteTimeout(u)));
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout]);
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback]);
// LED Flash
trilist.SetSigTrueAction(joinMap.EnableLedFlash, new Action(() => occController.SetLedFlashEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableLedFlash, new Action(() => occController.SetLedFlashEnable(false)));
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash]);
// Short Timeout
trilist.SetSigTrueAction(joinMap.EnableShortTimeout, new Action(() => occController.SetShortTimeoutState(true)));
trilist.SetSigTrueAction(joinMap.DisableShortTimeout, new Action(() => occController.SetShortTimeoutState(false)));
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout]);
// PIR Sensor
trilist.SetSigTrueAction(joinMap.EnablePir, new Action(() => occController.SetPirEnable(true)));
trilist.SetSigTrueAction(joinMap.DisablePir, new Action(() => occController.SetPirEnable(false)));
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir]);
// PIR Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState, new Action<bool>((b) => occController.IncrementPirSensitivityInOccupiedState(b)));
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState, new Action<bool>((b) => occController.DecrementPirSensitivityInOccupiedState(b)));
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState]);
// PIR Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState, new Action<bool>((b) => occController.IncrementPirSensitivityInVacantState(b)));
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState, new Action<bool>((b) => occController.DecrementPirSensitivityInVacantState(b)));
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState]);
#endregion
#region Dual Technology Sensor Stuff
var odtOccController = occController as GlsOdtOccupancySensorController;
if (odtOccController != null)
{
// OR When Vacated
trilist.SetBoolSigAction(joinMap.OrWhenVacated, new Action<bool>((b) => odtOccController.SetOrWhenVacatedState(b)));
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated]);
// AND When Vacated
trilist.SetBoolSigAction(joinMap.AndWhenVacated, new Action<bool>((b) => odtOccController.SetAndWhenVacatedState(b)));
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated]);
// Ultrasonic A Sensor
trilist.SetSigTrueAction(joinMap.EnableUsA, new Action(() => odtOccController.SetUsAEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableUsA, new Action(() => odtOccController.SetUsAEnable(false)));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA]);
// Ultrasonic B Sensor
trilist.SetSigTrueAction(joinMap.EnableUsB, new Action(() => odtOccController.SetUsBEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableUsB, new Action(() => odtOccController.SetUsBEnable(false)));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB]);
// US Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState, new Action<bool>((b) => odtOccController.IncrementUsSensitivityInOccupiedState(b)));
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState, new Action<bool>((b) => odtOccController.DecrementUsSensitivityInOccupiedState(b)));
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState]);
// US Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState, new Action<bool>((b) => odtOccController.IncrementUsSensitivityInVacantState(b)));
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState, new Action<bool>((b) => odtOccController.DecrementUsSensitivityInVacantState(b)));
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState]);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Devices.Common.Occupancy;
using PepperDash.Essentials.Core;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Bridges
{
public static class GlsOccupancySensorBaseControllerApiExtensions
{
public static void LinkToApi(this GlsOccupancySensorBaseController occController, BasicTriList trilist, uint joinStart, string joinMapKey)
{
GlsOccupancySensorBaseJoinMap joinMap = new GlsOccupancySensorBaseJoinMap();
var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
#region Single and Dual Sensor Stuff
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
// Occupied status
trilist.SetSigTrueAction(joinMap.ForceOccupied, new Action(() => occController.ForceOccupied()));
trilist.SetSigTrueAction(joinMap.ForceVacant, new Action(() => occController.ForceVacant()));
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback]);
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback]);
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback]);
// Timouts
trilist.SetUShortSigAction(joinMap.Timeout, new Action<ushort>((u) => occController.SetRemoteTimeout(u)));
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout]);
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback]);
// LED Flash
trilist.SetSigTrueAction(joinMap.EnableLedFlash, new Action(() => occController.SetLedFlashEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableLedFlash, new Action(() => occController.SetLedFlashEnable(false)));
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash]);
// Short Timeout
trilist.SetSigTrueAction(joinMap.EnableShortTimeout, new Action(() => occController.SetShortTimeoutState(true)));
trilist.SetSigTrueAction(joinMap.DisableShortTimeout, new Action(() => occController.SetShortTimeoutState(false)));
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout]);
// PIR Sensor
trilist.SetSigTrueAction(joinMap.EnablePir, new Action(() => occController.SetPirEnable(true)));
trilist.SetSigTrueAction(joinMap.DisablePir, new Action(() => occController.SetPirEnable(false)));
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir]);
// PIR Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState, new Action<bool>((b) => occController.IncrementPirSensitivityInOccupiedState(b)));
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState, new Action<bool>((b) => occController.DecrementPirSensitivityInOccupiedState(b)));
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState]);
// PIR Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState, new Action<bool>((b) => occController.IncrementPirSensitivityInVacantState(b)));
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState, new Action<bool>((b) => occController.DecrementPirSensitivityInVacantState(b)));
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState]);
#endregion
#region Dual Technology Sensor Stuff
var odtOccController = occController as GlsOdtOccupancySensorController;
if (odtOccController != null)
{
// OR When Vacated
trilist.SetBoolSigAction(joinMap.OrWhenVacated, new Action<bool>((b) => odtOccController.SetOrWhenVacatedState(b)));
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated]);
// AND When Vacated
trilist.SetBoolSigAction(joinMap.AndWhenVacated, new Action<bool>((b) => odtOccController.SetAndWhenVacatedState(b)));
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated]);
// Ultrasonic A Sensor
trilist.SetSigTrueAction(joinMap.EnableUsA, new Action(() => odtOccController.SetUsAEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableUsA, new Action(() => odtOccController.SetUsAEnable(false)));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA]);
// Ultrasonic B Sensor
trilist.SetSigTrueAction(joinMap.EnableUsB, new Action(() => odtOccController.SetUsBEnable(true)));
trilist.SetSigTrueAction(joinMap.DisableUsB, new Action(() => odtOccController.SetUsBEnable(false)));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB]);
// US Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState, new Action<bool>((b) => odtOccController.IncrementUsSensitivityInOccupiedState(b)));
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState, new Action<bool>((b) => odtOccController.DecrementUsSensitivityInOccupiedState(b)));
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState]);
// US Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState, new Action<bool>((b) => odtOccController.IncrementUsSensitivityInVacantState(b)));
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState, new Action<bool>((b) => odtOccController.DecrementUsSensitivityInVacantState(b)));
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState]);
//Sensor Raw States
odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback]);
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback]);
}
#endregion
}
}
}

View File

@@ -0,0 +1,43 @@
using System.Linq;
using Crestron.SimplSharp.Reflection;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Bridges
{
public class C2nRthsControllerJoinMap:JoinMapBase
{
public uint IsOnline { get; set; }
public uint Name { get; set; }
public uint Temperature { get; set; }
public uint Humidity { get; set; }
public uint TemperatureFormat { get; set; }
public C2nRthsControllerJoinMap()
{
//digital
IsOnline = 1;
TemperatureFormat = 2;
//Analog
Temperature = 2;
Humidity = 3;
//serial
Name = 1;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
var properties =
GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof(uint)).ToList();
foreach (var propertyInfo in properties)
{
propertyInfo.SetValue(this, (uint)propertyInfo.GetValue(this, null) + joinOffset, null);
}
}
}
}

View File

@@ -139,6 +139,7 @@ namespace PepperDash.Essentials.Bridges
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
HdcpSupportState = HdcpSupportState + joinOffset;
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
}
}
}

View File

@@ -18,6 +18,10 @@ namespace PepperDash.Essentials.Bridges
/// High when video sync is detected
/// </summary>
public uint VideoSyncStatus { get; set; }
/// <summary>
///
/// </summary>
public uint FreeRunEnabled { get; set; }
#endregion
#region Analogs
@@ -41,6 +45,16 @@ namespace PepperDash.Essentials.Bridges
/// Sets and reports the current HDCP state for the corresponding input port
/// </summary>
public uint Port2HdcpState { get; set; }
/// <summary>
/// Sets and reports the current VGA Brightness level
/// </summary>
public uint VgaBrightness { get; set; }
/// <summary>
/// Sets and reports the current VGA Contrast level
/// </summary>
public uint VgaContrast { get; set; }
#endregion
#region Serials
@@ -56,6 +70,7 @@ namespace PepperDash.Essentials.Bridges
// Digital
IsOnline = 1;
VideoSyncStatus = 2;
FreeRunEnabled = 3;
// Serial
CurrentInputResolution = 1;
// Analog
@@ -64,6 +79,8 @@ namespace PepperDash.Essentials.Bridges
HdcpSupportCapability = 3;
Port1HdcpState = 4;
Port2HdcpState = 5;
VgaBrightness = 6;
VgaContrast = 7;
}
public override void OffsetJoinNumbers(uint joinStart)
@@ -72,12 +89,15 @@ namespace PepperDash.Essentials.Bridges
IsOnline = IsOnline + joinOffset;
VideoSyncStatus = VideoSyncStatus + joinOffset;
FreeRunEnabled = FreeRunEnabled + joinOffset;
CurrentInputResolution = CurrentInputResolution + joinOffset;
VideoInput = VideoInput + joinOffset;
AudioInput = AudioInput + joinOffset;
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
Port1HdcpState = Port1HdcpState + joinOffset;
Port2HdcpState = Port2HdcpState + joinOffset;
VgaBrightness = VgaBrightness + joinOffset;
VgaContrast = VgaContrast + joinOffset;
}
}
}

View File

@@ -1,219 +1,230 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Bridges
{
public class GlsOccupancySensorBaseJoinMap : JoinMapBase
{
#region Digitals
/// <summary>
/// High when device is online
/// </summary>
public uint IsOnline { get; set; }
/// <summary>
/// Forces the device to report occupied status
/// </summary>
public uint ForceOccupied { get; set; }
/// <summary>
/// Forces the device to report vacant status
/// </summary>
public uint ForceVacant { get; set; }
/// <summary>
/// Enables raw status reporting
/// </summary>
public uint EnableRawStates { get; set; }
/// <summary>
/// High when raw occupancy is detected
/// </summary>
public uint RawOccupancyFeedback { get; set; }
/// <summary>
/// High when occupancy is detected
/// </summary>
public uint RoomOccupiedFeedback { get; set; }
/// <summary>
/// Hich when occupancy is detected in the grace period
/// </summary>
public uint GraceOccupancyDetectedFeedback { get; set; }
/// <summary>
/// High when vacancy is detected
/// </summary>
public uint RoomVacantFeedback { get; set; }
/// <summary>
/// Enables the LED Flash when set high
/// </summary>
public uint EnableLedFlash { get; set; }
/// <summary>
/// Disables the LED flash when set high
/// </summary>
public uint DisableLedFlash { get; set; }
/// <summary>
/// Enables the Short Timeout
/// </summary>
public uint EnableShortTimeout { get; set; }
/// <summary>
/// Disables the Short Timout
/// </summary>
public uint DisableShortTimeout { get; set; }
/// <summary>
/// Set high to enable one technology to trigger occupancy
/// </summary>
public uint OrWhenVacated { get; set; }
/// <summary>
/// Set high to require both technologies to trigger occupancy
/// </summary>
public uint AndWhenVacated { get; set; }
/// <summary>
/// Enables Ultrasonic Sensor A
/// </summary>
public uint EnableUsA { get; set; }
/// <summary>
/// Disables Ultrasonic Sensor A
/// </summary>
public uint DisableUsA { get; set; }
/// <summary>
/// Enables Ultrasonic Sensor B
/// </summary>
public uint EnableUsB { get; set; }
/// <summary>
/// Disables Ultrasonic Sensor B
/// </summary>
public uint DisableUsB { get; set; }
/// <summary>
/// Enables Pir
/// </summary>
public uint EnablePir { get; set; }
/// <summary>
/// Disables Pir
/// </summary>
public uint DisablePir { get; set; }
public uint IncrementUsInOccupiedState { get; set; }
public uint DecrementUsInOccupiedState { get; set; }
public uint IncrementUsInVacantState { get; set; }
public uint DecrementUsInVacantState { get; set; }
public uint IncrementPirInOccupiedState { get; set; }
public uint DecrementPirInOccupiedState { get; set; }
public uint IncrementPirInVacantState { get; set; }
public uint DecrementPirInVacantState { get; set; }
#endregion
#region Analogs
/// <summary>
/// Sets adn reports the remote timeout value
/// </summary>
public uint Timeout { get; set; }
/// <summary>
/// Reports the local timeout value
/// </summary>
public uint TimeoutLocalFeedback { get; set; }
/// <summary>
/// Sets the minimum internal photo sensor value and reports the current level
/// </summary>
public uint InternalPhotoSensorValue { get; set; }
/// <summary>
/// Sets the minimum external photo sensor value and reports the current level
/// </summary>
public uint ExternalPhotoSensorValue { get; set; }
public uint UsSensitivityInOccupiedState { get; set; }
public uint UsSensitivityInVacantState { get; set; }
public uint PirSensitivityInOccupiedState { get; set; }
public uint PirSensitivityInVacantState { get; set; }
#endregion
public GlsOccupancySensorBaseJoinMap()
{
IsOnline = 1;
ForceOccupied = 2;
ForceVacant = 3;
EnableRawStates = 4;
RoomOccupiedFeedback = 2;
GraceOccupancyDetectedFeedback = 3;
RoomVacantFeedback = 4;
RawOccupancyFeedback = 5;
EnableLedFlash = 11;
DisableLedFlash = 12;
EnableShortTimeout = 13;
DisableShortTimeout = 14;
OrWhenVacated = 15;
AndWhenVacated = 16;
EnableUsA = 17;
DisableUsA = 18;
EnableUsB = 19;
DisableUsB = 20;
EnablePir = 21;
DisablePir = 22;
DisablePir = 23;
IncrementUsInOccupiedState = 24;
DecrementUsInOccupiedState = 25;
IncrementUsInVacantState = 26;
DecrementUsInVacantState = 27;
IncrementPirInOccupiedState = 28;
DecrementPirInOccupiedState = 29;
IncrementPirInVacantState = 30;
DecrementPirInVacantState = 31;
Timeout = 1;
TimeoutLocalFeedback = 2;
InternalPhotoSensorValue = 3;
ExternalPhotoSensorValue = 4;
UsSensitivityInOccupiedState = 5;
UsSensitivityInVacantState = 6;
PirSensitivityInOccupiedState = 7;
PirSensitivityInVacantState = 8;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
IsOnline = IsOnline + joinOffset;
ForceOccupied = ForceOccupied + joinOffset;
ForceVacant = ForceVacant + joinOffset;
EnableRawStates = EnableRawStates + joinOffset;
RoomOccupiedFeedback = RoomOccupiedFeedback + joinOffset;
GraceOccupancyDetectedFeedback = GraceOccupancyDetectedFeedback + joinOffset;
RoomVacantFeedback = RoomVacantFeedback + joinOffset;
RawOccupancyFeedback = RawOccupancyFeedback + joinOffset;
EnableLedFlash = EnableLedFlash + joinOffset;
DisableLedFlash = DisableLedFlash + joinOffset;
EnableShortTimeout = EnableShortTimeout + joinOffset;
DisableShortTimeout = DisableShortTimeout + joinOffset;
OrWhenVacated = OrWhenVacated + joinOffset;
AndWhenVacated = AndWhenVacated + joinOffset;
EnableUsA = EnableUsA + joinOffset;
DisableUsA = DisableUsA + joinOffset;
EnableUsB = EnableUsB + joinOffset;
DisableUsB = DisableUsB + joinOffset;
EnablePir = EnablePir + joinOffset;
DisablePir = DisablePir + joinOffset;
DisablePir = DisablePir + joinOffset;
IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset;
DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset;
IncrementUsInVacantState = IncrementUsInVacantState + joinOffset;
DecrementUsInVacantState = DecrementUsInVacantState + joinOffset;
IncrementPirInOccupiedState = IncrementPirInOccupiedState + joinOffset;
DecrementPirInOccupiedState = DecrementPirInOccupiedState + joinOffset;
IncrementPirInVacantState = IncrementPirInVacantState + joinOffset;
DecrementPirInVacantState = DecrementPirInVacantState + joinOffset;
Timeout = Timeout + joinOffset;
TimeoutLocalFeedback = TimeoutLocalFeedback + joinOffset;
InternalPhotoSensorValue = InternalPhotoSensorValue + joinOffset;
ExternalPhotoSensorValue = ExternalPhotoSensorValue + joinOffset;
UsSensitivityInOccupiedState = UsSensitivityInOccupiedState + joinOffset;
UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset;
PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset;
PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Bridges
{
public class GlsOccupancySensorBaseJoinMap : JoinMapBase
{
#region Digitals
/// <summary>
/// High when device is online
/// </summary>
public uint IsOnline { get; set; }
/// <summary>
/// Forces the device to report occupied status
/// </summary>
public uint ForceOccupied { get; set; }
/// <summary>
/// Forces the device to report vacant status
/// </summary>
public uint ForceVacant { get; set; }
/// <summary>
/// Enables raw status reporting
/// </summary>
public uint EnableRawStates { get; set; }
/// <summary>
/// High when raw occupancy is detected
/// </summary>
public uint RawOccupancyFeedback { get; set; }
/// <summary>
/// High when PIR sensor detects motion
/// </summary>
public uint RawOccupancyPirFeedback { get; set; }
/// <summary>
/// High when US sensor detects motion
/// </summary>
public uint RawOccupancyUsFeedback { get; set; }
/// <summary>
/// High when occupancy is detected
/// </summary>
public uint RoomOccupiedFeedback { get; set; }
/// <summary>
/// Hich when occupancy is detected in the grace period
/// </summary>
public uint GraceOccupancyDetectedFeedback { get; set; }
/// <summary>
/// High when vacancy is detected
/// </summary>
public uint RoomVacantFeedback { get; set; }
/// <summary>
/// Enables the LED Flash when set high
/// </summary>
public uint EnableLedFlash { get; set; }
/// <summary>
/// Disables the LED flash when set high
/// </summary>
public uint DisableLedFlash { get; set; }
/// <summary>
/// Enables the Short Timeout
/// </summary>
public uint EnableShortTimeout { get; set; }
/// <summary>
/// Disables the Short Timout
/// </summary>
public uint DisableShortTimeout { get; set; }
/// <summary>
/// Set high to enable one technology to trigger occupancy
/// </summary>
public uint OrWhenVacated { get; set; }
/// <summary>
/// Set high to require both technologies to trigger occupancy
/// </summary>
public uint AndWhenVacated { get; set; }
/// <summary>
/// Enables Ultrasonic Sensor A
/// </summary>
public uint EnableUsA { get; set; }
/// <summary>
/// Disables Ultrasonic Sensor A
/// </summary>
public uint DisableUsA { get; set; }
/// <summary>
/// Enables Ultrasonic Sensor B
/// </summary>
public uint EnableUsB { get; set; }
/// <summary>
/// Disables Ultrasonic Sensor B
/// </summary>
public uint DisableUsB { get; set; }
/// <summary>
/// Enables Pir
/// </summary>
public uint EnablePir { get; set; }
/// <summary>
/// Disables Pir
/// </summary>
public uint DisablePir { get; set; }
public uint IncrementUsInOccupiedState { get; set; }
public uint DecrementUsInOccupiedState { get; set; }
public uint IncrementUsInVacantState { get; set; }
public uint DecrementUsInVacantState { get; set; }
public uint IncrementPirInOccupiedState { get; set; }
public uint DecrementPirInOccupiedState { get; set; }
public uint IncrementPirInVacantState { get; set; }
public uint DecrementPirInVacantState { get; set; }
#endregion
#region Analogs
/// <summary>
/// Sets adn reports the remote timeout value
/// </summary>
public uint Timeout { get; set; }
/// <summary>
/// Reports the local timeout value
/// </summary>
public uint TimeoutLocalFeedback { get; set; }
/// <summary>
/// Sets the minimum internal photo sensor value and reports the current level
/// </summary>
public uint InternalPhotoSensorValue { get; set; }
/// <summary>
/// Sets the minimum external photo sensor value and reports the current level
/// </summary>
public uint ExternalPhotoSensorValue { get; set; }
public uint UsSensitivityInOccupiedState { get; set; }
public uint UsSensitivityInVacantState { get; set; }
public uint PirSensitivityInOccupiedState { get; set; }
public uint PirSensitivityInVacantState { get; set; }
#endregion
public GlsOccupancySensorBaseJoinMap()
{
IsOnline = 1;
ForceOccupied = 2;
ForceVacant = 3;
EnableRawStates = 4;
RoomOccupiedFeedback = 2;
GraceOccupancyDetectedFeedback = 3;
RoomVacantFeedback = 4;
RawOccupancyFeedback = 5;
RawOccupancyPirFeedback = 6;
RawOccupancyUsFeedback = 7;
EnableLedFlash = 11;
DisableLedFlash = 12;
EnableShortTimeout = 13;
DisableShortTimeout = 14;
OrWhenVacated = 15;
AndWhenVacated = 16;
EnableUsA = 17;
DisableUsA = 18;
EnableUsB = 19;
DisableUsB = 20;
EnablePir = 21;
DisablePir = 22;
IncrementUsInOccupiedState = 23;
DecrementUsInOccupiedState = 24;
IncrementUsInVacantState = 25;
DecrementUsInVacantState = 26;
IncrementPirInOccupiedState = 27;
DecrementPirInOccupiedState = 28;
IncrementPirInVacantState = 29;
DecrementPirInVacantState = 30;
Timeout = 1;
TimeoutLocalFeedback = 2;
InternalPhotoSensorValue = 3;
ExternalPhotoSensorValue = 4;
UsSensitivityInOccupiedState = 5;
UsSensitivityInVacantState = 6;
PirSensitivityInOccupiedState = 7;
PirSensitivityInVacantState = 8;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
IsOnline = IsOnline + joinOffset;
ForceOccupied = ForceOccupied + joinOffset;
ForceVacant = ForceVacant + joinOffset;
EnableRawStates = EnableRawStates + joinOffset;
RoomOccupiedFeedback = RoomOccupiedFeedback + joinOffset;
GraceOccupancyDetectedFeedback = GraceOccupancyDetectedFeedback + joinOffset;
RoomVacantFeedback = RoomVacantFeedback + joinOffset;
RawOccupancyFeedback = RawOccupancyFeedback + joinOffset;
RawOccupancyPirFeedback = RawOccupancyPirFeedback + joinOffset;
RawOccupancyUsFeedback = RawOccupancyUsFeedback + joinOffset;
EnableLedFlash = EnableLedFlash + joinOffset;
DisableLedFlash = DisableLedFlash + joinOffset;
EnableShortTimeout = EnableShortTimeout + joinOffset;
DisableShortTimeout = DisableShortTimeout + joinOffset;
OrWhenVacated = OrWhenVacated + joinOffset;
AndWhenVacated = AndWhenVacated + joinOffset;
EnableUsA = EnableUsA + joinOffset;
DisableUsA = DisableUsA + joinOffset;
EnableUsB = EnableUsB + joinOffset;
DisableUsB = DisableUsB + joinOffset;
EnablePir = EnablePir + joinOffset;
DisablePir = DisablePir + joinOffset;
DisablePir = DisablePir + joinOffset;
IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset;
DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset;
IncrementUsInVacantState = IncrementUsInVacantState + joinOffset;
DecrementUsInVacantState = DecrementUsInVacantState + joinOffset;
IncrementPirInOccupiedState = IncrementPirInOccupiedState + joinOffset;
DecrementPirInOccupiedState = DecrementPirInOccupiedState + joinOffset;
IncrementPirInVacantState = IncrementPirInVacantState + joinOffset;
DecrementPirInVacantState = DecrementPirInVacantState + joinOffset;
Timeout = Timeout + joinOffset;
TimeoutLocalFeedback = TimeoutLocalFeedback + joinOffset;
InternalPhotoSensorValue = InternalPhotoSensorValue + joinOffset;
ExternalPhotoSensorValue = ExternalPhotoSensorValue + joinOffset;
UsSensitivityInOccupiedState = UsSensitivityInOccupiedState + joinOffset;
UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset;
PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset;
PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset;
}
}
}

View File

@@ -0,0 +1,49 @@
using System.Linq;
using Crestron.SimplSharp.Reflection;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Bridges
{
public class StatusSignControllerJoinMap:JoinMapBase
{
public uint IsOnline { get; set; }
public uint Name { get; set; }
public uint RedLed { get; set; }
public uint GreenLed { get; set; }
public uint BlueLed { get; set; }
public uint RedControl { get; set; }
public uint GreenControl { get; set; }
public uint BlueControl { get; set; }
public StatusSignControllerJoinMap()
{
//digital
IsOnline = 1;
RedControl = 2;
GreenControl = 3;
BlueControl = 4;
//Analog
RedLed = 2;
GreenLed = 3;
BlueLed = 4;
//string
Name = 1;
}
public override void OffsetJoinNumbers(uint joinStart)
{
var joinOffset = joinStart - 1;
var properties =
GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof (uint)).ToList();
foreach (var propertyInfo in properties)
{
propertyInfo.SetValue(this, (uint) propertyInfo.GetValue(this, null) + joinOffset, null);
}
}
}
}

View File

@@ -0,0 +1,65 @@
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Bridges
{
public static class StatusSignDeviceApiExtensions
{
public static void LinkToApi(this StatusSignController ssDevice, BasicTriList trilist, uint joinStart,
string joinMapKey)
{
var joinMap = new StatusSignControllerJoinMap();
var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<StatusSignControllerJoinMap>(joinMapSerialized);
joinMap.OffsetJoinNumbers(joinStart);
Debug.Console(1, ssDevice, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
trilist.SetBoolSigAction(joinMap.RedControl, b => EnableControl(trilist, joinMap, ssDevice));
trilist.SetBoolSigAction(joinMap.GreenControl, b => EnableControl(trilist, joinMap, ssDevice));
trilist.SetBoolSigAction(joinMap.BlueControl, b => EnableControl(trilist, joinMap, ssDevice));
trilist.SetUShortSigAction(joinMap.RedLed, u => SetColor(trilist, joinMap, ssDevice));
trilist.SetUShortSigAction(joinMap.GreenLed, u => SetColor(trilist, joinMap, ssDevice));
trilist.SetUShortSigAction(joinMap.BlueLed, u => SetColor(trilist, joinMap, ssDevice));
trilist.StringInput[joinMap.Name].StringValue = ssDevice.Name;
ssDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
ssDevice.RedLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RedControl]);
ssDevice.BlueLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.BlueControl]);
ssDevice.GreenLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.GreenControl]);
ssDevice.RedLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.RedLed]);
ssDevice.BlueLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.BlueLed]);
ssDevice.GreenLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.GreenLed]);
}
private static void EnableControl(BasicTriList triList, StatusSignControllerJoinMap joinMap,
StatusSignController device)
{
var redEnable = triList.BooleanOutput[joinMap.RedControl].BoolValue;
var greenEnable = triList.BooleanOutput[joinMap.GreenControl].BoolValue;
var blueEnable = triList.BooleanOutput[joinMap.BlueControl].BoolValue;
device.EnableLedControl(redEnable, greenEnable, blueEnable);
}
private static void SetColor(BasicTriList triList, StatusSignControllerJoinMap joinMap,
StatusSignController device)
{
var redBrightness = triList.UShortOutput[joinMap.RedLed].UShortValue;
var greenBrightness = triList.UShortOutput[joinMap.GreenLed].UShortValue;
var blueBrightness = triList.UShortOutput[joinMap.BlueLed].UShortValue;
device.SetColor(redBrightness, greenBrightness, blueBrightness);
}
}
}

View File

@@ -96,7 +96,7 @@ namespace PepperDash.Essentials
string directoryPrefix;
directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
Global.SetAssemblyVersion(string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build));

View File

@@ -119,9 +119,11 @@
<Compile Include="Bridges\AppleTvBridge.cs" />
<Compile Include="Bridges\BridgeBase.cs" />
<Compile Include="Bridges\BridgeFactory.cs" />
<Compile Include="Bridges\C2nRthsControllerBridge.cs" />
<Compile Include="Bridges\CameraControllerBridge.cs" />
<Compile Include="Bridges\AirMediaControllerBridge.cs" />
<Compile Include="Bridges\DmBladeChassisControllerBridge.cs" />
<Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\DmBladeChassisControllerJoinMap.cs" />
<Compile Include="Bridges\DmpsAudioOutputControllerBridge.cs" />
<Compile Include="Bridges\DmpsRoutingControllerBridge.cs" />
@@ -153,7 +155,9 @@
<Compile Include="Bridges\JoinMaps\IBasicCommunicationJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\IDigitalInputJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\GlsOccupancySensorBaseJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
<Compile Include="Bridges\StatusSignControllerBridge.cs" />
<Compile Include="Bridges\SystemMonitorBridge.cs" />
<Compile Include="Factory\DeviceFactory.cs" />
<Compile Include="Devices\Amplifier.cs" />

View File

@@ -106,12 +106,18 @@ namespace PepperDash.Essentials
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
+ Global.DirectorySeparator + "sgd" + Global.DirectorySeparator + props.SgdFile;
var sgdName = Global.FilePathPrefix + "sgd" + Global.DirectorySeparator + props.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "ERROR: Smart object file '{0}' not present. Exiting TSW load", sgdName);
return;
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);

View File

@@ -16,38 +16,29 @@ Essentials Framework is a collection of C# / Simpl# Pro libraries that can be ut
## Dependencies
The PepperDash.Core SIMPL# library is required. It is referenced as a submodule and will be automatically checked out when cloning this repo if set to recurse submodules. This allows different builds of the PepperDash.Core library to be reference by checking out the desired submodule commit.
The [PepperDash.Core](https://github.com/PepperDash/PepperDashCore) SIMPL# library is required. It is referenced as a submodule and will be automatically checked out when cloning this repo if set to recurse submodules. This allows different builds of the PepperDash.Core library to be referenced by checking out the desired submodule commit.
## Utilization
Essentials was originally conceptualized as a standalone application for running control system logic entirely in Simpl# Pro. It is primarily designed around accomplishing this goal, but during development, it became obvious that it could easily be leveraged to also serve as a partner application to one or more SIMPL Windows programs.
Utilization of Essentials Framework falls into the following categories:
1. Standalone Control System Application for controlling one or more rooms
1. Standalone Control System Application for controlling one or more rooms. See [Standalone Use](https://github.com/PepperDash/Essentials/wiki/Standalone-Use#standalone-application)
2. Partner Application to a SIMPL Windows program. This allows for several useful advantages
2. Partner Application to a SIMPL Windows program. This allows for several useful advantages. See [SIMPL Windows Bridging](https://github.com/PepperDash/Essentials/wiki/SIMPL-Bridging#simpl-windows-bridging)
- Dynamic device instantiation. Devices can be defined in configuration and instantiated at runtime and then "bridged" to a SIMPL Windows program via EISC.
- Dynamic device instantiation. Devices can be defined in configuration and instantiated at runtime and then bridged to a SIMPL Windows program via EISC.
- Advanced logic. Some logic operations that cannot be affectively accomplished in SIMPL Windows (ex. JSON/XML serialization/deserialization, database operations, etc.) can be done in the Simpl# Pro environment and the necessary input and output "bridged" to a SIMPL Windows program via EISC.
- Advanced logic. Some logic operations that cannot be affectively accomplished in SIMPL Windows (ex. JSON/XML serialization/deserialization, database operations, etc.) can be done in the Simpl# Pro environment and the necessary input and output bridged to a SIMPL Windows program via EISC.
3. Hybrid Application that may contain elements of both standalone control and SIMPL partner application integration.
- There may be a use case where a device can only be defined in a single application, but that device may need to be interacted with from multiple applications. The device can be defined in an Essentials application, interacted with in that application and also "bridged" to one or more SIMPL Windows applications.
- There may be a use case where a device can only be defined in a single application, but that device may need to be interacted with from multiple applications. The device can be defined in an Essentials application, interacted with in that application and also bridged to one or more SIMPL Windows applications.
## Documentation
For detailed documentation, follow this [LINK](https://github.com/PepperDash/EssentialsFramework/wiki) to the Wiki.
For detailed documentation, see the [Wiki](https://github.com/PepperDash/EssentialsFramework/wiki).
## How-To (Getting Started)
To help understand Essentials Framework, we recommend starting with the current [Example Build]() and loading it to a Crestron 3-Series processor.
1. First, load the PepperDashEssentials.cpz to the processor in program slot 1 and start the program.
2. On first boot, the Essentials Application will build the necessary configuration folder structure in the User/Program1/ path.
3. Load the ExampleEssentialsConfigurationFile.json to the User/Program1/ folder.
4. Reset the program via console (progreset -p:1). The program will load the example configuration file.
5. Launch the EssentialsExampleXpanel.vtz project. You can interact with the program (which uses simulated device logic to emulate a real commercial huddle room with presentation, audio and video calling capabilities).
6. Via console, you can run the (**devlist:1**) command to get some insight into what has been loaded from the configuration file into the system . This will print the basic device information in the form of ["key"] "Name". The "key" value is what we can use to interact with each device uniquely.
7. Run the command (**devprops:1 display-1**). This will print the real-time property values of the device with key "display-1".
8. Run the command (**devmethods:1 display-1**). This will print the public methods available for the device with key "display-1".
9. Run the command (**devjson:1 {"deviceKey":"display-1","methodName":"PowerOn", "params": []}**). This will call the method PowerOn() on the device with key "display-1".
See [Getting Started](https://github.com/PepperDash/Essentials/wiki/Get-started#how-to-get-started)

View File

@@ -0,0 +1,44 @@
using System;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.CrestronIO
{
public class C2nRthsController:CrestronGenericBaseDevice
{
private C2nRths _device;
public IntFeedback TemperatureFeedback { get; private set; }
public IntFeedback HumidityFeedback { get; private set; }
public C2nRthsController(string key, string name, GenericBase hardware) : base(key, name, hardware)
{
_device = hardware as C2nRths;
TemperatureFeedback = new IntFeedback(() => _device.TemperatureFeedback.UShortValue);
HumidityFeedback = new IntFeedback(() => _device.HumidityFeedback.UShortValue);
_device.BaseEvent += DeviceOnBaseEvent;
}
private void DeviceOnBaseEvent(GenericBase device, BaseEventArgs args)
{
switch (args.EventId)
{
case C2nRths.TemperatureFeedbackEventId:
TemperatureFeedback.FireUpdate();
break;
case C2nRths.HumidityFeedbackEventId:
HumidityFeedback.FireUpdate();
break;
}
}
public void SetTemperatureFormat(bool setToC)
{
_device.TemperatureFormat.BoolValue = setToC;
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.CrestronIO
{
public class StatusSignController:CrestronGenericBaseDevice
{
private StatusSign _device;
public BoolFeedback RedLedEnabledFeedback { get; private set; }
public BoolFeedback GreenLedEnabledFeedback { get; private set; }
public BoolFeedback BlueLedEnabledFeedback { get; private set; }
public IntFeedback RedLedBrightnessFeedback { get; private set; }
public IntFeedback GreenLedBrightnessFeedback { get; private set; }
public IntFeedback BlueLedBrightnessFeedback { get; private set; }
public StatusSignController(string key, string name, GenericBase hardware) : base(key, name, hardware)
{
_device = hardware as StatusSign;
RedLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint) StatusSign.Led.eLedColor.Red]
.ControlFeedback.BoolValue);
GreenLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint) StatusSign.Led.eLedColor.Green]
.ControlFeedback.BoolValue);
BlueLedEnabledFeedback =
new BoolFeedback(
() =>
_device.Leds[(uint) StatusSign.Led.eLedColor.Blue]
.ControlFeedback.BoolValue);
RedLedBrightnessFeedback =
new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Red].BrightnessFeedback);
GreenLedBrightnessFeedback =
new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Green].BrightnessFeedback);
BlueLedBrightnessFeedback =
new IntFeedback(() => (int) _device.Leds[(uint) StatusSign.Led.eLedColor.Blue].BrightnessFeedback);
_device.BaseEvent += _device_BaseEvent;
}
void _device_BaseEvent(GenericBase device, BaseEventArgs args)
{
switch (args.EventId)
{
case StatusSign.LedBrightnessFeedbackEventId:
RedLedBrightnessFeedback.FireUpdate();
GreenLedBrightnessFeedback.FireUpdate();
BlueLedBrightnessFeedback.FireUpdate();
break;
case StatusSign.LedControlFeedbackEventId:
RedLedEnabledFeedback.FireUpdate();
GreenLedEnabledFeedback.FireUpdate();
BlueLedEnabledFeedback.FireUpdate();
break;
}
}
public void EnableLedControl(bool red, bool green, bool blue)
{
_device.Leds[(uint) StatusSign.Led.eLedColor.Red].Control.BoolValue = red;
_device.Leds[(uint)StatusSign.Led.eLedColor.Green].Control.BoolValue = green;
_device.Leds[(uint)StatusSign.Led.eLedColor.Blue].Control.BoolValue = blue;
}
public void SetColor(uint red, uint green, uint blue)
{
try
{
_device.Leds[(uint)StatusSign.Led.eLedColor.Red].Brightness =
(StatusSign.Led.eBrightnessPercentageValues)SimplSharpDeviceHelper.PercentToUshort(red);
}
catch (InvalidOperationException)
{
Debug.Console(1, this, "Error converting value to Red LED brightness. value: {0}", red);
}
try
{
_device.Leds[(uint)StatusSign.Led.eLedColor.Green].Brightness =
(StatusSign.Led.eBrightnessPercentageValues)SimplSharpDeviceHelper.PercentToUshort(green);
}
catch (InvalidOperationException)
{
Debug.Console(1, this, "Error converting value to Green LED brightness. value: {0}", green);
}
try
{
_device.Leds[(uint)StatusSign.Led.eLedColor.Blue].Brightness =
(StatusSign.Led.eBrightnessPercentageValues)SimplSharpDeviceHelper.PercentToUshort(blue);
}
catch (InvalidOperationException)
{
Debug.Console(1, this, "Error converting value to Blue LED brightness. value: {0}", blue);
}
}
}
}

View File

@@ -1,156 +1,169 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// A bridge class to cover the basic features of GenericBase hardware
/// </summary>
public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
{
public virtual GenericBase Hardware { get; protected set; }
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
public BoolFeedback IsOnline { get; private set; }
public BoolFeedback IsRegistered { get; private set; }
public StringFeedback IpConnectionsText { get; private set; }
/// <summary>
/// Used by implementing classes to prevent registration with Crestron TLDM. For
/// devices like RMCs and TXs attached to a chassis.
/// </summary>
public bool PreventRegistration { get; protected set; }
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
: base(key, name)
{
Feedbacks = new FeedbackCollection<Feedback>();
Hardware = hardware;
IsOnline = new BoolFeedback("IsOnlineFeedback", () => Hardware.IsOnline);
IsRegistered = new BoolFeedback("IsRegistered", () => Hardware.Registered);
IpConnectionsText = new StringFeedback("IpConnectionsText", () =>
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
AddToFeedbackList(IsOnline, IsRegistered, IpConnectionsText);
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
}
/// <summary>
/// Make sure that overriding classes call this!
/// Registers the Crestron device, connects up to the base events, starts communication monitor
/// </summary>
public override bool CustomActivate()
{
Debug.Console(0, this, "Activating");
if (!PreventRegistration)
{
//Debug.Console(1, this, " Does not require registration. Skipping");
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
}
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
return true;
}
/// <summary>
/// This disconnects events and unregisters the base hardware device.
/// </summary>
/// <returns></returns>
public override bool Deactivate()
{
CommunicationMonitor.Stop();
Hardware.OnlineStatusChange -= Hardware_OnlineStatusChange;
return Hardware.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
}
/// <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);
}
}
}
}
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
if (args.DeviceOnLine)
{
foreach (var feedback in Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
}
}
#region IStatusMonitor Members
public StatusMonitorBase CommunicationMonitor { get; private set; }
#endregion
#region IUsageTracking Members
public UsageTracking UsageTracker { get; set; }
#endregion
}
//***********************************************************************************
public class CrestronGenericBaseDeviceEventIds
{
public const uint IsOnline = 1;
public const uint IpConnectionsText =2;
}
/// <summary>
/// Adds logging to Register() failure
/// </summary>
public static class GenericBaseExtensions
{
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
{
var result = device.Register();
var level = result == eDeviceRegistrationUnRegistrationResponse.Success ?
Debug.ErrorLogLevel.Notice : Debug.ErrorLogLevel.Error;
Debug.Console(0, level, "Register device result: '{0}', type '{1}', result {2}", key, device, result);
//if (result != eDeviceRegistrationUnRegistrationResponse.Success)
//{
// Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
//}
return result;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// A bridge class to cover the basic features of GenericBase hardware
/// </summary>
public class CrestronGenericBaseDevice : Device, IOnline, IHasFeedback, ICommunicationMonitor, IUsageTracking
{
public virtual GenericBase Hardware { get; protected set; }
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
public BoolFeedback IsOnline { get; private set; }
public BoolFeedback IsRegistered { get; private set; }
public StringFeedback IpConnectionsText { get; private set; }
/// <summary>
/// Used by implementing classes to prevent registration with Crestron TLDM. For
/// devices like RMCs and TXs attached to a chassis.
/// </summary>
public bool PreventRegistration { get; protected set; }
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
: base(key, name)
{
Feedbacks = new FeedbackCollection<Feedback>();
Hardware = hardware;
IsOnline = new BoolFeedback("IsOnlineFeedback", () => Hardware.IsOnline);
IsRegistered = new BoolFeedback("IsRegistered", () => Hardware.Registered);
IpConnectionsText = new StringFeedback("IpConnectionsText", () =>
{
if (Hardware.ConnectedIpList != null)
return string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray());
else
return string.Empty;
});
AddToFeedbackList(IsOnline, IpConnectionsText);
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, hardware, 120000, 300000);
}
/// <summary>
/// Make sure that overriding classes call this!
/// Registers the Crestron device, connects up to the base events, starts communication monitor
/// </summary>
public override bool CustomActivate()
{
Debug.Console(0, this, "Activating");
if (!PreventRegistration)
{
//Debug.Console(1, this, " Does not require registration. Skipping");
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
IsRegistered.FireUpdate();
}
foreach (var f in Feedbacks)
{
f.FireUpdate();
}
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
return true;
}
/// <summary>
/// This disconnects events and unregisters the base hardware device.
/// </summary>
/// <returns></returns>
public override bool Deactivate()
{
CommunicationMonitor.Stop();
Hardware.OnlineStatusChange -= Hardware_OnlineStatusChange;
var success = Hardware.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
IsRegistered.FireUpdate();
return success;
}
/// <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);
}
}
}
}
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
Debug.Console(2, this, "OnlineStatusChange Event. Online = {0}", args.DeviceOnLine);
foreach (var feedback in Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
}
#region IStatusMonitor Members
public StatusMonitorBase CommunicationMonitor { get; private set; }
#endregion
#region IUsageTracking Members
public UsageTracking UsageTracker { get; set; }
#endregion
}
//***********************************************************************************
public class CrestronGenericBaseDeviceEventIds
{
public const uint IsOnline = 1;
public const uint IpConnectionsText =2;
}
/// <summary>
/// Adds logging to Register() failure
/// </summary>
public static class GenericBaseExtensions
{
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
{
var result = device.Register();
var level = result == eDeviceRegistrationUnRegistrationResponse.Success ?
Debug.ErrorLogLevel.Notice : Debug.ErrorLogLevel.Error;
Debug.Console(0, level, "Register device result: '{0}', type '{1}', result {2}", key, device, result);
//if (result != eDeviceRegistrationUnRegistrationResponse.Success)
//{
// Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
//}
return result;
}
}
}

View File

@@ -4,10 +4,11 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.Core
{
@@ -59,6 +60,20 @@ namespace PepperDash.Essentials.Core
return new CenIoDigIn104Controller(key, name, new Crestron.SimplSharpPro.GeneralIO.CenIoDi104(ipid, Global.ControlSystem));
}
if (typeName == "statussign")
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
return new StatusSignController(key, name, new StatusSign(cresnetId, Global.ControlSystem));
}
if (typeName == "c2nrths")
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
return new C2nRthsController(key, name, new C2nRths(cresnetId, Global.ControlSystem));
}
// then check for types that have been added by plugin dlls.
if (FactoryMethods.ContainsKey(typeName))

View File

@@ -26,6 +26,17 @@ namespace PepperDash.Essentials.Core
/// </summary>
public static string FilePathPrefix { get; private set; }
/// <summary>
/// The file path prefix to the applciation directory
/// </summary>
public static string ApplicationDirectoryPathPrefix
{
get
{
return Crestron.SimplSharp.CrestronIO.Directory.GetApplicationDirectory();
}
}
/// <summary>
/// Returns the directory separator character based on the running OS
/// </summary>

View File

@@ -64,7 +64,7 @@
</Reference>
<Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.Remotes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -119,6 +119,7 @@
<Compile Include="Config\Essentials\ConfigWriter.cs" />
<Compile Include="Config\Essentials\EssentialsConfig.cs" />
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
<Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" />
<Compile Include="Crestron IO\Inputs\CenIoDigIn104Controller.cs" />
<Compile Include="Crestron IO\Inputs\GenericDigitalInputDevice.cs" />
<Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" />
@@ -126,6 +127,7 @@
<Compile Include="Crestron IO\IOPortConfig.cs" />
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
<Compile Include="Crestron IO\StatusSign\StatusSignController.cs" />
<Compile Include="Devices\CodecInterfaces.cs" />
<Compile Include="Devices\CrestronProcessor.cs" />
<Compile Include="Devices\DeviceApiBase.cs" />

View File

@@ -0,0 +1,11 @@
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.Plugins
{
public interface IPluginDeviceConfig
{
string MinimumEssentialsFrameworkVersion { get; }
IKeyed BuildDevice(DeviceConfig dc);
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace PepperDash.Essentials.Core.Plugins
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class PluginEntryPointAttribute : Attribute
{
private readonly string _uniqueKey;
public string UniqueKey {
get { return _uniqueKey; }
}
public PluginEntryPointAttribute(string key)
{
_uniqueKey = key;
}
}
}

View File

@@ -3,5 +3,5 @@
[assembly: AssemblyTitle("PepperDashEssentialsBase")]
[assembly: AssemblyCompany("PepperDash Technology Corp")]
[assembly: AssemblyProduct("PepperDashEssentialsBase")]
[assembly: AssemblyCopyright("Copyright © Ppperdash 2019")]
[assembly: AssemblyCopyright("Copyright © Pepperdash 2019")]
[assembly: AssemblyVersion("1.4.0.*")]

View File

@@ -23,6 +23,10 @@ namespace PepperDash.Essentials.Core
public StringFeedback TimeRemainingFeedback { get; private set; }
public bool CountsDown { get; set; }
/// <summary>
/// The number of seconds to countdown
/// </summary>
public int SecondsToCount { get; set; }
public DateTime StartTime { get; private set; }
@@ -31,7 +35,7 @@ namespace PepperDash.Essentials.Core
CTimer SecondTimer;
/// <summary>
///
/// Constructor
/// </summary>
/// <param name="key"></param>
public SecondsCountdownTimer(string key)
@@ -61,7 +65,7 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
///
/// Starts the Timer
/// </summary>
public void Start()
{
@@ -82,7 +86,7 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
///
/// Restarts the timer
/// </summary>
public void Reset()
{
@@ -91,7 +95,7 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
///
/// Cancels the timer (without triggering it to finish)
/// </summary>
public void Cancel()
{

View File

@@ -104,9 +104,12 @@ namespace PepperDash.Essentials.DM
}
var controller = new DmChassisController(key, name, chassis);
// add the cards and port names
foreach (var kvp in properties.InputSlots)
controller.AddInputCard(kvp.Value, kvp.Key);
foreach (var kvp in properties.InputSlots)
{
controller.AddInputCard(kvp.Value, kvp.Key);
}
foreach (var kvp in properties.OutputSlots)
{
controller.AddOutputCard(kvp.Value, kvp.Key);
@@ -188,11 +191,18 @@ namespace PepperDash.Essentials.DM
SystemIdBusyFeedback = new BoolFeedback(() => { return (Chassis as DmMDMnxn).SystemIdBusy.BoolValue; });
InputCardHdcpCapabilityFeedbacks = new Dictionary<uint, IntFeedback>();
InputCardHdcpCapabilityTypes = new Dictionary<uint, eHdcpCapabilityType>();
}
public override bool CustomActivate()
{
Debug.Console(2, this, "Setting up feedbacks.");
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
// Setup Output Card Feedbacks
for (uint x = 1; x <= Chassis.NumberOfOutputs; x++)
{
var tempX = x;
var tempX = x;
Debug.Console(2, this, "Setting up feedbacks for output slot: {0}", tempX);
if (Chassis.Outputs[tempX] != null)
{
@@ -235,26 +245,41 @@ namespace PepperDash.Essentials.DM
}
});
OutputAudioRouteNameFeedbacks[tempX] = new StringFeedback(() =>
{
if (Chassis.Outputs[tempX].AudioOutFeedback != null)
{
if (Chassis.Outputs[tempX].AudioOutFeedback != null)
{
return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue;
}
else
{
return NoRouteText;
return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue;
}
else
{
return NoRouteText;
}
});
}
});
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
{
return Chassis.Outputs[tempX].EndpointOnlineFeedback;
});
}
else
{
Debug.Console(2, this, "No Output Card defined in slot: {0}", tempX);
}
};
// Setup Input Card Feedbacks
for (uint x = 1; x <= Chassis.NumberOfInputs; x++)
{
var tempX = x;
Debug.Console(2, this, "Setting up feedbacks for input slot: {0}", tempX);
CheckForHdcp2Property(tempX);
if (Chassis.Inputs[tempX] != null)
{
UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() =>
{
if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; }
@@ -279,7 +304,7 @@ namespace PepperDash.Essentials.DM
}
});
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() =>
{
return Chassis.Inputs[tempX].EndpointOnlineFeedback;
});
@@ -288,6 +313,8 @@ namespace PepperDash.Essentials.DM
{
var inputCard = Chassis.Inputs[tempX];
Debug.Console(2, this, "Adding InputCardHdcpCapabilityFeedback for slot: {0}", inputCard);
if (inputCard.Card is DmcHd)
{
InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport;
@@ -342,8 +369,32 @@ namespace PepperDash.Essentials.DM
return 0;
});
}
}
}
else
{
Debug.Console(2, this, "No Input Card defined in slot: {0}", tempX);
}
}
return base.CustomActivate();
}
/// <summary>
/// Checks for presence of config property defining if the input card supports HDCP2.
/// If not found, assumes false.
/// </summary>
/// <param name="inputSlot">Input Slot</param>
void CheckForHdcp2Property(uint inputSlot)
{
if (!PropertiesConfig.InputSlotSupportsHdcp2.ContainsKey(inputSlot))
{
Debug.Console(0, this, Debug.ErrorLogLevel.Warning,
@"Properties Config does not define inputSlotSupportsHdcp2 entry for input card: {0}. Assuming false.
If HDCP2 is required, HDCP control/feedback will not fucntion correctly!", inputSlot);
PropertiesConfig.InputSlotSupportsHdcp2.Add(inputSlot, false);
}
else
Debug.Console(2, this, "inputSlotSupportsHdcp2 for input card: {0} = {1}", inputSlot, PropertiesConfig.InputSlotSupportsHdcp2[inputSlot]);
}
/// <summary>
///
@@ -566,6 +617,13 @@ namespace PepperDash.Essentials.DM
var cecPort2 = outputCard.Card2.HdmiOutput;
AddDmcHdoPorts(number, cecPort1, cecPort2);
}
else if (type == "dmc4kzhdo")
{
var outputCard = new Dmc4kzHdoSingle(number, Chassis);
var cecPort1 = outputCard.Card1.HdmiOutput;
var cecPort2 = outputCard.Card2.HdmiOutput;
AddDmcHdoPorts(number, cecPort1, cecPort2);
}
else if (type == "dmchdo")
{
var outputCard = new DmcHdoSingle(number, Chassis);
@@ -579,13 +637,13 @@ namespace PepperDash.Essentials.DM
var cecPort1 = outputCard.Card1.HdmiOutput;
AddDmcCoPorts(number, cecPort1);
}
else if (type == "dmc4kzcohd")
{
else if (type == "dmc4kzcohd")
{
var outputCard = new Dmc4kzCoHdSingle(number, Chassis);
var cecPort1 = outputCard.Card1.HdmiOutput;
AddDmcCoPorts(number, cecPort1);
}
else if (type == "dmccohd")
else if (type == "dmccohd")
{
var outputCard = new DmcCoHdSingle(number, Chassis);
var cecPort1 = outputCard.Card1.HdmiOutput;

View File

@@ -19,7 +19,7 @@ namespace PepperDash.Essentials.DM
/// <summary>
/// Controller class for all DM-TX-201C/S/F transmitters
/// </summary>
public class DmTx200Controller : DmTxControllerBase, ITxRouting, IHasFeedback
public class DmTx200Controller : DmTxControllerBase, ITxRouting, IHasFeedback, IHasFreeRun, IVgaBrightnessContrastControls
{
public DmTx200C2G Tx { get; private set; }
@@ -32,8 +32,10 @@ namespace PepperDash.Essentials.DM
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; }
public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
/// <summary>
/// Helps get the "real" inputs, including when in Auto
@@ -115,7 +117,7 @@ namespace PepperDash.Essentials.DM
HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () =>
{
if (tx.HdmiInput.HdpcSupportOnFeedback.BoolValue)
if (tx.HdmiInput.HdcpSupportOnFeedback.BoolValue)
return 1;
else
return 0;
@@ -123,6 +125,14 @@ namespace PepperDash.Essentials.DM
HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
tx.VgaInput.VideoControls.ControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(VideoControls_ControlChange);
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
@@ -170,6 +180,21 @@ namespace PepperDash.Essentials.DM
DmOutput.Port = Tx.DmOutput;
}
void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{
var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
if (id == VideoControlsEventIds.BrightnessFeedbackEventId)
{
VgaBrightnessFeedback.FireUpdate();
}
else if (id == VideoControlsEventIds.ContrastFeedbackEventId)
{
VgaContrastFeedback.FireUpdate();
}
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
ActiveVideoInputFeedback.FireUpdate();
@@ -191,6 +216,40 @@ namespace PepperDash.Essentials.DM
return base.CustomActivate();
}
/// <summary>
/// Enables or disables free run
/// </summary>
/// <param name="enable"></param>
public void SetFreeRunEnabled(bool enable)
{
if (enable)
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Enabled;
}
else
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Disabled;
}
}
/// <summary>
/// Sets the VGA brightness level
/// </summary>
/// <param name="level"></param>
public void SetVgaBrightness(ushort level)
{
Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
}
/// <summary>
/// Sets the VGA contrast level
/// </summary>
/// <param name="level"></param>
public void SetVgaContrast(ushort level)
{
Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
}
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);

View File

@@ -19,7 +19,7 @@ namespace PepperDash.Essentials.DM
/// <summary>
/// Controller class for all DM-TX-201C/S/F transmitters
/// </summary>
public class DmTx201XController : DmTxControllerBase, ITxRouting, IHasFeedback
public class DmTx201XController : DmTxControllerBase, ITxRouting, IHasFeedback, IHasFreeRun, IVgaBrightnessContrastControls
{
public DmTx201S Tx { get; private set; } // uses the 201S class as it is the base class for the 201C
@@ -33,8 +33,10 @@ namespace PepperDash.Essentials.DM
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; }
public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
/// <summary>
/// Helps get the "real" inputs, including when in Auto
@@ -116,12 +118,19 @@ namespace PepperDash.Essentials.DM
HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () =>
{
if (tx.HdmiInput.HdpcSupportOnFeedback.BoolValue)
if (tx.HdmiInput.HdcpSupportOnFeedback.BoolValue)
return 1;
else
return 0;
});
FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
tx.VgaInput.VideoControls.ControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(VideoControls_ControlChange);
HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
var combinedFuncs = new VideoStatusFuncsWrapper
@@ -156,7 +165,7 @@ namespace PepperDash.Essentials.DM
};
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
DmOutput = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, null, this);
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
@@ -174,6 +183,21 @@ namespace PepperDash.Essentials.DM
DmOutput.Port = Tx.DmOutput;
}
void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{
var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
if (id == VideoControlsEventIds.BrightnessFeedbackEventId)
{
VgaBrightnessFeedback.FireUpdate();
}
else if (id == VideoControlsEventIds.ContrastFeedbackEventId)
{
VgaContrastFeedback.FireUpdate();
}
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
ActiveVideoInputFeedback.FireUpdate();
@@ -183,8 +207,7 @@ namespace PepperDash.Essentials.DM
}
public override bool CustomActivate()
{
{
Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiInput, a.EventId);
Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(HdmiInput, a.EventId);
@@ -195,6 +218,46 @@ namespace PepperDash.Essentials.DM
return base.CustomActivate();
}
/// <summary>
/// Enables or disables free run
/// </summary>
/// <param name="enable"></param>
public void SetFreeRunEnabled(bool enable)
{
if (enable)
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Enabled;
}
else
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Disabled;
}
}
/// <summary>
/// Sets the VGA brightness level
/// </summary>
/// <param name="level"></param>
public void SetVgaBrightness(ushort level)
{
Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
}
/// <summary>
/// Sets the VGA contrast level
/// </summary>
/// <param name="level"></param>
public void SetVgaContrast(ushort level)
{
Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
}
/// <summary>
/// Switches the audio/video source based on the integer value (0-Auto, 1-HDMI, 2-VGA, 3-Disable)
/// </summary>
/// <param name="input"></param>
/// <param name="output"></param>
/// <param name="type"></param>
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
@@ -250,6 +313,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate();
}
}
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
@@ -264,6 +328,10 @@ namespace PepperDash.Essentials.DM
{
HdmiInHdcpCapabilityFeedback.FireUpdate();
}
else if (args.EventId == EndpointInputStreamEventIds.FreeRunFeedbackEventId)
{
FreeRunEnabledFeedback.FireUpdate();
}
}
/// <summary>

View File

@@ -17,7 +17,7 @@ namespace PepperDash.Essentials.DM
{
using eVst = DmTx401C.eSourceSelection;
public class DmTx401CController : DmTxControllerBase, ITxRouting, IHasFeedback, IIROutputPorts, IComPorts
public class DmTx401CController : DmTxControllerBase, ITxRouting, IHasFeedback, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
{
public DmTx401C Tx { get; private set; }
@@ -34,6 +34,11 @@ namespace PepperDash.Essentials.DM
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
/// <summary>
/// Helps get the "real" inputs, including when in Auto
/// </summary>
@@ -122,7 +127,7 @@ namespace PepperDash.Essentials.DM
HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () =>
{
if (tx.HdmiInput.HdpcSupportOnFeedback.BoolValue)
if (tx.HdmiInput.HdcpSupportOnFeedback.BoolValue)
return 1;
else
return 0;
@@ -130,6 +135,13 @@ namespace PepperDash.Essentials.DM
HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
tx.VgaInput.VideoControls.ControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(VideoControls_ControlChange);
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
@@ -269,6 +281,55 @@ namespace PepperDash.Essentials.DM
}
}
void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{
var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
if (id == VideoControlsEventIds.BrightnessFeedbackEventId)
{
VgaBrightnessFeedback.FireUpdate();
}
else if (id == VideoControlsEventIds.ContrastFeedbackEventId)
{
VgaContrastFeedback.FireUpdate();
}
}
/// <summary>
/// Enables or disables free run
/// </summary>
/// <param name="enable"></param>
public void SetFreeRunEnabled(bool enable)
{
if (enable)
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Enabled;
}
else
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Disabled;
}
}
/// <summary>
/// Sets the VGA brightness level
/// </summary>
/// <param name="level"></param>
public void SetVgaBrightness(ushort level)
{
Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
}
/// <summary>
/// Sets the VGA contrast level
/// </summary>
/// <param name="level"></param>
public void SetVgaContrast(ushort level)
{
Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
}
/// <summary>
/// Relays the input stream change to the appropriate RoutingInputPort.
/// </summary>

View File

@@ -19,7 +19,7 @@ namespace PepperDash.Essentials.DM
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
public class DmTx4k302CController : DmTxControllerBase, ITxRouting, IHasFeedback,
IIROutputPorts, IComPorts
IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
{
public DmTx4k302C Tx { get; private set; }
@@ -35,8 +35,10 @@ namespace PepperDash.Essentials.DM
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; }
public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
/// <summary>
/// Helps get the "real" inputs, including when in Auto
@@ -122,6 +124,13 @@ namespace PepperDash.Essentials.DM
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
tx.VgaInput.VideoControls.ControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(VideoControls_ControlChange);
var combinedFuncs = new VideoStatusFuncsWrapper
{
@@ -181,6 +190,21 @@ namespace PepperDash.Essentials.DM
DmOut.Port = Tx.DmOutput;
}
void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{
var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
if (id == VideoControlsEventIds.BrightnessFeedbackEventId)
{
VgaBrightnessFeedback.FireUpdate();
}
else if (id == VideoControlsEventIds.ContrastFeedbackEventId)
{
VgaContrastFeedback.FireUpdate();
}
}
public override bool CustomActivate()
@@ -199,6 +223,42 @@ namespace PepperDash.Essentials.DM
return base.CustomActivate();
}
/// <summary>
/// Enables or disables free run
/// </summary>
/// <param name="enable"></param>
public void SetFreeRunEnabled(bool enable)
{
if (enable)
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Enabled;
}
else
{
Tx.VgaInput.FreeRun = eDmFreeRunSetting.Disabled;
}
}
/// <summary>
/// Sets the VGA brightness level
/// </summary>
/// <param name="level"></param>
public void SetVgaBrightness(ushort level)
{
Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
}
/// <summary>
/// Sets the VGA contrast level
/// </summary>
/// <param name="level"></param>
public void SetVgaContrast(ushort level)
{
Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
}
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.DM
{
/// <summary>
/// Defines a device capable of setting the Free Run state of a VGA input and reporting feedback
/// </summary>
public interface IHasFreeRun
{
BoolFeedback FreeRunEnabledFeedback { get; }
void SetFreeRunEnabled(bool enable);
}
/// <summary>
/// Defines a device capable of adjusting VGA settings
/// </summary>
public interface IVgaBrightnessContrastControls
{
IntFeedback VgaBrightnessFeedback { get; }
IntFeedback VgaContrastFeedback { get; }
void SetVgaBrightness(ushort level);
void SetVgaContrast(ushort level);
}
}

View File

@@ -96,6 +96,7 @@
<Compile Include="Chassis\DmpsInternalVirtualDmTxController.cs" />
<Compile Include="Chassis\DmpsRoutingController.cs" />
<Compile Include="Chassis\HdMdNxM4kEController.cs" />
<Compile Include="Endpoints\Transmitters\TxInterfaces.cs" />
<Compile Include="IDmSwitch.cs" />
<Compile Include="Config\DmpsRoutingConfig.cs" />
<Compile Include="Config\DmRmcConfig.cs" />

View File

@@ -73,17 +73,18 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{
// Iterate the meeting list and check if any meeting need to do anythingk
const double meetingTimeEpsilon = 0.0001;
foreach (Meeting m in Meetings)
{
eMeetingEventChangeType changeType = eMeetingEventChangeType.Unkown;
if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start
changeType = eMeetingEventChangeType.MeetingStartWarning;
else if (m.TimeToMeetingStart.TotalMinutes == 0) // Meeting Start
else if (Math.Abs(m.TimeToMeetingStart.TotalMinutes) < meetingTimeEpsilon) // Meeting Start
changeType = eMeetingEventChangeType.MeetingStart;
else if (m.TimeToMeetingEnd.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to end
changeType = eMeetingEventChangeType.MeetingEndWarning;
else if (m.TimeToMeetingEnd.TotalMinutes == 0) // Meeting has ended
else if (Math.Abs(m.TimeToMeetingEnd.TotalMinutes) < meetingTimeEpsilon) // Meeting has ended
changeType = eMeetingEventChangeType.MeetingEnd;
if (changeType != eMeetingEventChangeType.Unkown)

View File

@@ -24,7 +24,11 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
public GlsOdtOccupancySensorController(string key, string name, GlsOdtCCn sensor)
@@ -38,11 +42,15 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue);
UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue);
UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue);
RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue);
RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue);
UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue);
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
}
/// <summary>
@@ -52,20 +60,23 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId)
AndWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId)
OrWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId)
UltrasonicAEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId)
UltrasonicBEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId)
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId)
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
{
if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId)
AndWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId)
OrWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId)
UltrasonicAEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId)
UltrasonicBEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId)
RawOccupancyPirFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId)
RawOccupancyUsFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId)
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId)
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
base.OccSensor_GlsOccupancySensorChange(device, args);
}

View File

@@ -336,8 +336,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
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);