Compare commits

..

1 Commits

Author SHA1 Message Date
Heath Volmer
006ef9e02e Merge pull request #1 in PEC/essentials from development to release
* commit '5f5c963fa44763e6ec4d9bdf1a4008e183dd1873':
  Fixes StartSharing() method in CiscoSparkCodec to only execute if the PresentationSource is > 0 Fixes ecs-612 by adding property to UsageTracking object to determing if the usage tracker is already running.
  resolves ecs-611 and all other known bugs from onsite testing at NYU
  Update debug messages for SIP phone number extraction
  Added objects back to xStatus lost in merge and fixed regex pattern for extracting phone number. Added formatting call to room phone number when displayed on header
  Additional fix to top next meeting warning popups when room is on
  Updated getters for SIP URI and phone number to use correct status properties.  Updates to xConfiguration and xStatus classes to address differences between Spark and Spark Plus
  Fixed Stop Sharing button method to use the room route action method to sync source fb.  Updated xStatus, xConfiguration, booking and phonebook deserialization classes in codec to match onsite return results from NYU room kit plus codec
  Resolved ecs-582,602,608
2017-10-27 11:44:29 -04:00
1050 changed files with 57266 additions and 152797 deletions

View File

@@ -1,37 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]-"
labels: bug
assignees: ''
---
**Was this bug identified in a specific build version?**
Please note the build version where this bug was identified
**Describe the bug**
A clear and concise description of what the bug is.
**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

@@ -1,21 +0,0 @@
---
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.

View File

@@ -1,27 +0,0 @@
---
name: Request for Information
about: Request specific information about capabilities of the framework
title: "[RFI]-"
labels: RFI
assignees: ''
---
**What is your request?**
Please provide as much detail as possible.
**What is the intended use case**
- [ ] Essentials Standalone Application
- [ ] Essentials + SIMPL Windows Hybrid
**User Interface Requirements**
- [ ] Not Applicable (logic only)
- [ ] Crestron Smart Graphics Touchpanel
- [ ] Cisco Touch10
- [ ] Mobile Control
- [ ] Crestron CH5 Touchpanel interface
**Additional context**
Add any other context or screenshots about the request here.

View File

@@ -1,23 +0,0 @@
$latestVersion = [version]"2.0.0"
$newVersion = [version]$latestVersion
$phase = ""
$newVersionString = ""
switch -regex ($Env:GITHUB_REF) {
'^refs\/pull\/*.' {
$phase = 'beta';
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/feature-2.0.0\/*.' {
$phase = 'alpha'
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
'development-2.0.0' {
$phase = 'beta'
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
}
Write-Output $newVersionString

View File

@@ -1,59 +0,0 @@
$latestVersions = $(git tag --merged origin/main)
$latestVersion = [version]"0.0.0"
Write-Host "GITHUB_REF: $($Env:GITHUB_REF)"
Write-Host "GITHUB_HEAD_REF: $($Env:GITHUB_HEAD_REF)"
Write-Host "GITHUB_BASE_REF: $($Env:GITHUB_BASE_REF)"
Foreach ($version in $latestVersions) {
Write-Host $version
try {
if (([version]$version) -ge $latestVersion) {
$latestVersion = $version
Write-Host "Setting latest version to: $latestVersion"
}
}
catch {
Write-Host "Unable to convert $($version). Skipping"
continue;
}
}
$newVersion = [version]$latestVersion
$phase = ""
$newVersionString = ""
switch -regex ($Env:GITHUB_REF) {
'^refs\/pull\/*.' {
$splitRef = $Env:GITHUB_REF -split "/"
$phase = "pr$($splitRef[2])"
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/main*.' {
$newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build
}
'^refs\/heads\/feature\/*.' {
$phase = 'alpha'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/release\/*.' {
$splitRef = $Env:GITHUB_REF -split "/"
$version = [version]($splitRef[-1] -replace "v", "")
$phase = 'rc'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $version.Major, $version.Minor, $version.Build, $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/development*.' {
$phase = 'beta'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/hotfix\/*.' {
$phase = 'hotfix'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/bugfix\/*.' {
$phase = 'hotfix'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
}
Write-Output $newVersionString

View File

@@ -1,40 +0,0 @@
function Update-SourceVersion {
Param ([string]$Version)
#$fullVersion = $Version
$baseVersion = [regex]::Match($Version, "(\d+.\d+.\d+).*").captures.groups[1].value
$NewAssemblyVersion = AssemblyVersion(" + $baseVersion + .*")
Write-Output "AssemblyVersion = $NewAssemblyVersion"
$NewAssemblyInformationalVersion = AssemblyInformationalVersion(" + $Version + ")
Write-Output "AssemblyInformationalVersion = $NewAssemblyInformationalVersion"
foreach ($o in $input) {
Write-output $o.FullName
$TmpFile = $o.FullName + .tmp
get-content $o.FullName |
ForEach-Object {
$_ -replace AssemblyVersion\(".*"\), $NewAssemblyVersion } |
ForEach-Object {
$_ -replace AssemblyInformationalVersion\(".*"\), $NewAssemblyInformationalVersion
} > $TmpFile
move-item $TmpFile $o.FullName -force
}
}
function Update-AllAssemblyInfoFiles ( $version ) {
foreach ($file in AssemblyInfo.cs, AssemblyInfo.vb ) {
get-childitem -Path $Env:GITHUB_WORKSPACE -recurse | Where-Object { $_.Name -eq $file } | Update-SourceVersion $version ;
}
}
# validate arguments
$r = [System.Text.RegularExpressions.Regex]::Match($args[0], "\d+\.\d+\.\d+.*");
if ($r.Success) {
Write-Output "Updating Assembly Version to $args ...";
Update-AllAssemblyInfoFiles $args[0];
}
else {
Write-Output ;
Write-Output Error: Input version does not match x.y.z format!
Write-Output ;
Write-Output "Unable to apply version to AssemblyInfo.cs files";
}

View File

@@ -1,45 +0,0 @@
# Uncomment these for local testing
# $Env:GITHUB_WORKSPACE = "C:\Working Directories\PD\essentials"
# $Env:SOLUTION_FILE = "PepperDashEssentials"
# $Env:VERSION = "0.0.0-buildType-test"
# Sets the root directory for the operation
$destination = "$($Env:GITHUB_HOME)\output"
New-Item -ItemType Directory -Force -Path ($destination)
Get-ChildItem ($destination)
$exclusions = @(git submodule foreach --quiet 'echo $name')
$exclusions += "Newtonsoft.Compact.Json.dll"
# Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.dll", "*.nuspec" | ForEach-Object {
$allowed = $true;
# Exclude any files in submodules
foreach ($exclude in $exclusions) {
if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
$allowed = $false;
break;
}
}
if ($allowed) {
Write-Host "allowing $($_)"
$_;
}
} | Copy-Item -Destination ($destination) -Force
Write-Host "Getting matching files..."
# Get any files from the output folder that match the following extensions
Get-ChildItem -Path $destination | Where-Object { ($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz")) } | ForEach-Object {
# Replace the extensions with dll and xml and create an array
# Removed dll file capture, as previous step should capture all of them. Add if needed-> $($_ -replace "cpz|clz|cplz", "dll"),
$filenames = @($($_ -replace "cpz|clz|cplz", "xml"))
Write-Host "Filenames:"
Write-Host $filenames
if ($filenames.length -gt 0) {
# Attempt to get the files and return them to the output directory
Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
}
}
Get-ChildItem -Path $destination\*.cpz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" }
Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force
Write-Host "Output Contents post Zip"
Get-ChildItem -Path $destination

View File

@@ -1,22 +0,0 @@
name: Build PepperDash Essentials
on:
push:
branches:
- '**'
jobs:
getVersion:
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-getversion.yml@main
secrets: inherit
build-4Series:
uses: PepperDash/workflow-templates/.github/workflows/essentialsplugins-4Series-builds.yml@main
secrets: inherit
needs: getVersion
if: needs.getVersion.outputs.newVersion == 'true'
with:
newVersion: ${{ needs.getVersion.outputs.newVersion }}
version: ${{ needs.getVersion.outputs.version }}
tag: ${{ needs.getVersion.outputs.tag }}
channel: ${{ needs.getVersion.outputs.channel }}
bypassPackageCheck: true

View File

@@ -1,45 +0,0 @@
name: Publish Docs
# Trigger the action on push to main
on:
push:
branches:
- main
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
actions: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
publish-docs:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Dotnet Setup
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x
- run: dotnet tool update -g docfx
- run: docfx ./docs/docfx.json
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload entire repository
path: './docs/_site'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

378
.gitignore vendored
View File

@@ -20,380 +20,4 @@ obj/
[Rr]elease*/
_ReSharper*/
SIMPLSharpLogs/
*.projectinfo
essentials-framework/EssentialDMTestConfig/
output/
packages/
PepperDashEssentials-0.0.0-buildType-test.zip
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
.DS_Store
/._PepperDash.Essentials.sln
.vscode/settings.json
_site/
api/
*.DS_Store
/._PepperDash.Essentials.4Series.sln
dotnet
*.projectinfo

View File

@@ -1,36 +0,0 @@
{
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"releaseRules": [
{ "scope": "force-patch", "release": "patch" },
{ "scope": "no-release", "release": false }
]
}
],
"@semantic-release/release-notes-generator",
["@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
}
],
[
"@semantic-release/exec",
{
"verifyReleaseCmd": "echo \"newVersion=true\" >> $GITHUB_OUTPUT",
"publishCmd": "echo \"version=${nextRelease.version}\" >> $GITHUB_OUTPUT && echo \"tag=${nextRelease.gitTag}\" >> $GITHUB_OUTPUT && echo \"type=${nextRelease.type}\" >> $GITHUB_OUTPUT && echo \"channel=${nextRelease.channel}\" >> $GITHUB_OUTPUT"
}
]
],
"branches": [
"main",
{"name": "development", "prerelease": "beta", "channel": "beta"},
{"name": "release", "prerelease": "rc", "channel": "rc"},
{
"name": "replace-me-feature-branch",
"prerelease": "replace-me-prerelease",
"channel": "replace-me-prerelease"
}
]
}

View File

@@ -1,9 +0,0 @@
{
"recommendations": [
"ms-dotnettools.vscode-dotnet-runtime",
"ms-dotnettools.csharp",
"ms-dotnettools.csdevkit",
"vivaxy.vscode-conventional-commits",
"mhutchie.git-graph"
]
}

View File

@@ -1,110 +0,0 @@
# 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 Essentials from your own
repository. As we identify and recognize extensions that are of general interest to Essentials, 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

@@ -1,282 +0,0 @@
# Crestron Library Usage Analysis - PepperDash Essentials
This document provides a comprehensive analysis of Crestron classes and interfaces used throughout the PepperDash Essentials framework, organized by namespace and library component.
## Executive Summary
The PepperDash Essentials framework extensively leverages Crestron SDK components across 100+ files, providing abstractions for:
- Control system hardware (processors, touchpanels, IO devices)
- Communication interfaces (Serial, TCP/IP, SSH, CEC, IR)
- Device management and routing
- User interface components and smart objects
- System monitoring and diagnostics
## 1. Core Crestron Libraries
### 1.1 Crestron.SimplSharp
**Primary Usage**: Foundational framework components, collections, and basic types.
**Key Files**:
- Multiple files across all projects use `Crestron.SimplSharp` namespaces
- Provides basic C# runtime support for Crestron processors
### 1.2 Crestron.SimplSharpPro
**Primary Usage**: Main hardware abstraction layer for Crestron devices.
**Key Classes Used**:
#### CrestronControlSystem
- **File**: `/src/PepperDash.Essentials/ControlSystem.cs`
- **Usage**: Base class for the main control system implementation
- **Implementation**: `public class ControlSystem : CrestronControlSystem, ILoadConfig`
#### Device (Base Class)
- **Files**: 50+ files inherit from or use this class
- **Key Implementations**:
- `/src/PepperDash.Core/Device.cs` - Core device abstraction
- `/src/PepperDash.Essentials.Core/Devices/EssentialsDevice.cs` - Extended device base
- `/src/PepperDash.Essentials.Core/Room/Room.cs` - Room device implementation
- `/src/PepperDash.Essentials.Core/Devices/CrestronProcessor.cs` - Processor device wrapper
#### BasicTriList
- **Files**: 30+ files use this class extensively
- **Primary Usage**: Touchpanel communication and SIMPL bridging
- **Key Files**:
- `/src/PepperDash.Essentials.Core/Touchpanels/TriListExtensions.cs` - Extension methods for signal handling
- `/src/PepperDash.Essentials.Core/Devices/EssentialsBridgeableDevice.cs` - Bridge interface
- `/src/PepperDash.Essentials.Core/Touchpanels/ModalDialog.cs` - UI dialog implementation
#### BasicTriListWithSmartObject
- **Files**: Multiple touchpanel and UI files
- **Usage**: Enhanced touchpanel support with smart object integration
- **Key Files**:
- `/src/PepperDash.Essentials.Core/Touchpanels/Interfaces.cs` - Interface definitions
- `/src/PepperDash.Essentials.Core/SmartObjects/SubpageReferenceList/SubpageReferenceList.cs`
## 2. Communication Hardware
### 2.1 Serial Communication (ComPort)
**Primary Class**: `ComPort`
**Key Files**:
- `/src/PepperDash.Essentials.Core/Comm and IR/ComPortController.cs`
- `/src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs`
**Usage Pattern**:
```csharp
public class ComPortController : Device, IBasicCommunicationWithStreamDebugging
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
```
**Interface Support**: `IComPorts` - Used for devices that provide multiple COM ports
### 2.2 IR Communication (IROutputPort)
**Primary Class**: `IROutputPort`
**Key Files**:
- `/src/PepperDash.Essentials.Core/Devices/IrOutputPortController.cs`
- `/src/PepperDash.Essentials.Core/Devices/GenericIRController.cs`
- `/src/PepperDash.Essentials.Core/Comm and IR/IRPortHelper.cs`
**Usage Pattern**:
```csharp
public class IrOutputPortController : Device
IROutputPort IrPort;
public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath)
```
### 2.3 CEC Communication (ICec)
**Primary Interface**: `ICec`
**Key Files**:
- `/src/PepperDash.Essentials.Core/Comm and IR/CecPortController.cs`
- `/src/PepperDash.Essentials.Core/Comm and IR/CommFactory.cs`
**Usage Pattern**:
```csharp
public class CecPortController : Device, IBasicCommunicationWithStreamDebugging
public static ICec GetCecPort(ControlPropertiesConfig config)
```
## 3. Input/Output Hardware
### 3.1 Digital Input
**Primary Interface**: `IDigitalInput`
**Key Files**:
- `/src/PepperDash.Essentials.Core/CrestronIO/GenericDigitalInputDevice.cs`
- `/src/PepperDash.Essentials.Core/Microphone Privacy/MicrophonePrivacyController.cs`
**Usage Pattern**:
```csharp
public List<IDigitalInput> Inputs { get; private set; }
void AddInput(IDigitalInput input)
```
### 3.2 Versiport Support
**Key Files**:
- `/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportInputDevice.cs`
- `/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportAnalogInputDevice.cs`
- `/src/PepperDash.Essentials.Core/CrestronIO/GenericVersiportOutputDevice.cs`
**Usage**: Provides flexible I/O port configuration for various signal types
## 4. Touchpanel Hardware
### 4.1 MPC3 Touchpanel
**Primary Class**: `MPC3Basic`
**Key File**: `/src/PepperDash.Essentials.Core/Touchpanels/Mpc3Touchpanel.cs`
**Usage Pattern**:
```csharp
public class Mpc3TouchpanelController : Device
readonly MPC3Basic _touchpanel;
_touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic;
```
### 4.2 TSW Series Support
**Evidence**: References found in messenger files and mobile control components
**Usage**: Integrated through mobile control messaging system for TSW touchpanel features
## 5. Timer and Threading
### 5.1 CTimer
**Primary Class**: `CTimer`
**Key File**: `/src/PepperDash.Core/PasswordManagement/PasswordManager.cs`
**Usage Pattern**:
```csharp
Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Started"));
Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Reset"));
```
## 6. Networking and Communication
### 6.1 Ethernet Communication
**Libraries Used**:
- `Crestron.SimplSharpPro.EthernetCommunication`
- `Crestron.SimplSharp.Net.Utilities.EthernetHelper`
**Key Files**:
- `/src/PepperDash.Core/Comm/GenericTcpIpClient.cs`
- `/src/PepperDash.Core/Comm/GenericTcpIpServer.cs`
- `/src/PepperDash.Core/Comm/GenericSecureTcpIpClient.cs`
- `/src/PepperDash.Core/Comm/GenericSshClient.cs`
- `/src/PepperDash.Core/Comm/GenericUdpServer.cs`
**Usage Pattern**:
```csharp
public class GenericTcpIpClient : Device, ISocketStatusWithStreamDebugging, IAutoReconnect
public class GenericSecureTcpIpClient : Device, ISocketStatusWithStreamDebugging, IAutoReconnect
```
## 7. Device Management Libraries
### 7.1 DeviceSupport
**Library**: `Crestron.SimplSharpPro.DeviceSupport`
**Usage**: Core device support infrastructure used throughout the framework
### 7.2 DM (DigitalMedia)
**Library**: `Crestron.SimplSharpPro.DM`
**Usage**: Digital media routing and switching support
**Evidence**: Found in routing configuration and DM output card references
## 8. User Interface Libraries
### 8.1 UI Components
**Library**: `Crestron.SimplSharpPro.UI`
**Usage**: User interface elements and touchpanel controls
### 8.2 Smart Objects
**Key Files**:
- `/src/PepperDash.Essentials.Core/SmartObjects/SmartObjectDynamicList.cs`
- `/src/PepperDash.Essentials.Core/SmartObjects/SubpageReferenceList/SubpageReferenceList.cs`
**Usage**: Advanced UI components with dynamic content
## 9. System Monitoring and Diagnostics
### 9.1 Diagnostics
**Library**: `Crestron.SimplSharpPro.Diagnostics`
**Usage**: System health monitoring and performance tracking
### 9.2 System Information
**Key Files**:
- `/src/PepperDash.Essentials.Core/Monitoring/SystemMonitorController.cs`
**Usage**: Provides system status, Ethernet information, and program details
## 10. Integration Patterns
### 10.1 SIMPL Bridging
**Pattern**: Extensive use of `BasicTriList` for SIMPL integration
**Files**: Bridge classes throughout the framework implement `LinkToApi` methods:
```csharp
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
```
### 10.2 Device Factory Pattern
**Implementation**: Factory classes create hardware-specific implementations
**Example**: `CommFactory.cs` provides communication device creation
### 10.3 Extension Methods
**Pattern**: Extensive use of extension methods for Crestron classes
**Example**: `TriListExtensions.cs` adds 30+ extension methods to `BasicTriList`
## 11. Signal Processing
### 11.1 Signal Types
**Bool Signals**: Digital control and feedback
**UShort Signals**: Analog values and numeric data
**String Signals**: Text and configuration data
**Implementation**: Comprehensive signal handling in `TriListExtensions.cs`
## 12. Error Handling and Logging
**Pattern**: Consistent use of Crestron's Debug logging throughout
**Examples**:
```csharp
Debug.LogMessage(LogEventLevel.Information, "Device {0} is not a valid device", dc.PortDeviceKey);
Debug.LogMessage(LogEventLevel.Debug, "Error Waking Panel. Maybe testing with Xpanel?");
```
## 13. Threading and Synchronization
**Components**:
- CTimer for time-based operations
- Thread-safe collections and patterns
- Event-driven programming models
## Conclusion
The PepperDash Essentials framework demonstrates sophisticated integration with the Crestron ecosystem, leveraging:
- **Core Infrastructure**: CrestronControlSystem, Device base classes
- **Communication**: COM, IR, CEC, TCP/IP, SSH protocols
- **Hardware Abstraction**: Touchpanels, I/O devices, processors
- **User Interface**: Smart objects, signal processing, SIMPL bridging
- **System Services**: Monitoring, diagnostics, device management
This analysis shows that Essentials serves as a comprehensive middleware layer, abstracting Crestron hardware complexities while providing modern software development patterns and practices.
---
*Generated: [Current Date]*
*Framework Version: PepperDash Essentials (Based on codebase analysis)*

View File

@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash_Essentials_Core", "PepperDashEssentialsBase\PepperDash_Essentials_Core.csproj", "{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class ComPortController : Device, IBasicCommunication
{
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
public bool IsConnected { get { return true; } }
ComPort Port;
ComPort.ComPortSpec Spec;
public ComPortController(string key, ComPort port, ComPort.ComPortSpec spec)
: base(key)
{
Port = port;
Spec = spec;
//IsConnected = new BoolFeedback(CommonBoolCue.IsConnected, () => true);
if (Port.Parent is CrestronControlSystem)
{
var result = Port.Register();
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(0, this, "WARNING: Cannot register Com port: {0}", result);
return; // false
}
}
var specResult = Port.SetComPortSpec(Spec);
if (specResult != 0)
{
Debug.Console(0, this, "WARNING: Cannot set comspec");
return; // false
}
Port.SerialDataReceived += new ComPortDataReceivedEvent(Port_SerialDataReceived);
}
~ComPortController()
{
Port.SerialDataReceived -= Port_SerialDataReceived;
}
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
{
OnDataReceived(args.SerialData);
}
void OnDataReceived(string s)
{
var bytesHandler = BytesReceived;
if (bytesHandler != null)
{
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived;
if (textHandler != null)
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
}
public override bool Deactivate()
{
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
}
#region IBasicCommunication Members
public void SendText(string text)
{
Port.Send(text);
}
public void SendBytes(byte[] bytes)
{
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
Port.Send(text);
}
public void Connect()
{
}
public void Disconnect()
{
}
#endregion
/// <summary>
///
/// </summary>
/// <param name="s"></param>
public void SimulateReceive(string s)
{
// split out hex chars and build string
var split = Regex.Split(s, @"(\\[Xx][0-9a-fA-F][0-9a-fA-F])");
StringBuilder b = new StringBuilder();
foreach (var t in split)
{
if (t.StartsWith(@"\") && t.Length == 4)
b.Append((char)(Convert.ToByte(t.Substring(2, 2), 16)));
else
b.Append(t);
}
OnDataReceived(b.ToString());
}
}
}

View File

@@ -1,6 +1,4 @@

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -23,37 +21,31 @@ namespace PepperDash.Essentials.Core
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (objectType == typeof(ComPort.ComPortSpec?))
if (objectType == typeof(ComPort.ComPortSpec))
{
var newSer = new JsonSerializer();
newSer.Converters.Add(new ComSpecPropsJsonConverter());
newSer.ObjectCreationHandling = ObjectCreationHandling.Replace;
return newSer.Deserialize<ComPort.ComPortSpec?>(reader);
return newSer.Deserialize<ComPort.ComPortSpec>(reader);
}
return null;
}
/// <summary>
/// CanConvert method
///
/// </summary>
/// <inheritdoc />
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ComPort.ComPortSpec?);
return objectType == typeof(ComPort.ComPortSpec);
}
public override bool CanRead { get { return true; } }
/// <summary>
/// Gets or sets the CanWrite
/// This converter will not be used for writing
/// </summary>
/// <inheritdoc />
public override bool CanWrite { get { return false; } }
/// <summary>
/// WriteJson method
/// </summary>
/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
@@ -61,11 +53,12 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
/// Represents a ComSpecPropsJsonConverter
/// The gist of this converter: The comspec JSON comes in with normal values that need to be converted
/// into enum names. This converter takes the value and applies the appropriate enum's name prefix to the value
/// and then returns the enum value using Enum.Parse. NOTE: Does not write
/// </summary>
public class ComSpecPropsJsonConverter : JsonConverter
{
/// <inheritdoc />
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ComPort.eComBaudRates)
@@ -77,18 +70,11 @@ namespace PepperDash.Essentials.Core
|| objectType == typeof(ComPort.eComStopBits);
}
/// <summary>
/// Gets or sets the CanRead
/// </summary>
/// <inheritdoc />
public override bool CanRead { get { return true; } }
/// <summary>
/// ReadJson method
/// </summary>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//Debug.LogMessage(LogEventLevel.Verbose, "ReadJson type: " + objectType.Name);
//Debug.Console(2, "ReadJson type: " + objectType.Name);
if (objectType == typeof(ComPort.eComBaudRates))
return Enum.Parse(typeof(ComPort.eComBaudRates), "ComspecBaudRate" + reader.Value, false);
else if (objectType == typeof(ComPort.eComDataBits))
@@ -106,10 +92,6 @@ namespace PepperDash.Essentials.Core
return null;
}
/// <summary>
/// WriteJson method
/// </summary>
/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();

View File

@@ -0,0 +1,178 @@
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public class CommFactory
{
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
{
try
{
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
(deviceConfig.Properties["control"].ToString());
//Debug.Console(2, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
}
catch (Exception e)
{
Debug.Console(0, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
return null;
}
}
/// <summary>
/// Returns a comm method of either com port, TCP, SSH
/// </summary>
/// <param name="deviceConfig">The Device config object</param>
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
{
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
if (controlConfig == null)
return null;
IBasicCommunication comm = null;
try
{
var c = controlConfig.TcpSshProperties;
switch (controlConfig.Method)
{
case eControlMethod.Com:
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort(controlConfig), controlConfig.ComParams);
break;
case eControlMethod.IR:
break;
case eControlMethod.Ssh:
{
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
ssh.AutoReconnect = c.AutoReconnect;
if(ssh.AutoReconnect)
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
comm = ssh;
break;
}
case eControlMethod.Tcpip:
{
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
tcp.AutoReconnect = c.AutoReconnect;
if (tcp.AutoReconnect)
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
comm = tcp;
break;
}
case eControlMethod.Telnet:
break;
default:
break;
}
}
catch (Exception e)
{
Debug.Console(0, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
deviceConfig.Properties.ToString(), e);
}
// put it in the device manager if it's the right flavor
var comDev = comm as Device;
if (comDev != null)
DeviceManager.AddDevice(comDev);
return comm;
}
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
{
var comPar = config.ComParams;
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
return dev.ComPorts[config.ControlPortNumber];
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
return null;
}
/// <summary>
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
/// return the ControlSystem object from the Global class.
/// </summary>
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
{
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
&& Global.ControlSystem is IComPorts)
return Global.ControlSystem;
else
{
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
if (dev == null)
Debug.Console(0, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
return dev;
}
}
}
/// <summary>
///
/// </summary>
public class EssentialsControlPropertiesConfig :
PepperDash.Core.ControlPropertiesConfig
{
// ****** All of these things, except for #Pro-specific com stuff, were
// moved into PepperDash.Core to help non-pro PortalSync.
//public eControlMethod Method { get; set; }
//public string ControlPortDevKey { get; set; }
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] // In case "null" is present in config on this value
//public uint ControlPortNumber { get; set; }
//public TcpSshPropertiesConfig TcpSshProperties { get; set; }
//public string IrFile { get; set; }
//public ComPortConfig ComParams { get; set; }
[JsonConverter(typeof(ComSpecJsonConverter))]
public ComPort.ComPortSpec ComParams { get; set; }
//public string IpId { get; set; }
//[JsonIgnore]
//public uint IpIdInt { get { return Convert.ToUInt32(IpId, 16); } }
//public char EndOfLineChar { get; set; }
///// <summary>
///// Defaults to Environment.NewLine;
///// </summary>
//public string EndOfLineString { get; set; }
//public string DeviceReadyResponsePattern { get; set; }
//public EssentialsControlPropertiesConfig()
//{
// EndOfLineString = CrestronEnvironment.NewLine;
//}
}
public class IrControlSpec
{
public string PortDeviceKey { get; set; }
public uint PortNumber { get; set; }
public string File { get; set; }
}
//public enum eControlMethod
//{
// None = 0, Com, IpId, IR, Ssh, Tcpip, Telnet
//}
}

View File

@@ -1,6 +1,4 @@

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class ConsoleCommMockDevice : Device, ICommunicationMonitor
{
public IBasicCommunication Communication { get; private set; }
public CommunicationGather PortGather { get; private set; }
public StatusMonitorBase CommunicationMonitor { get; private set; }
/// <summary>
/// Defaults to \x0a
/// </summary>
public string LineEnding { get; set; }
/// <summary>
/// Set to true to show responses in full hex
/// </summary>
public bool ShowHexResponse { get; set; }
public ConsoleCommMockDevice(string key, string name, ConsoleCommMockDevicePropertiesConfig props, IBasicCommunication comm)
:base(key, name)
{
Communication = comm;
PortGather = new CommunicationGather(Communication, '\x0d');
PortGather.LineReceived += this.Port_LineReceived;
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
LineEnding = props.LineEnding;
}
public override bool CustomActivate()
{
Communication.Connect();
CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
CommunicationMonitor.Start();
CrestronConsole.AddNewConsoleCommand(SendLine, "send" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => Communication.Connect(), "con" + Key, "", ConsoleAccessLevelEnum.AccessOperator);
return true;
}
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
{
if (Debug.Level == 2)
Debug.Console(2, this, "RX: '{0}'",
ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text);
}
void SendLine(string s)
{
//if (Debug.Level == 2)
// Debug.Console(2, this, " Send '{0}'", ComTextHelper.GetEscapedText(s));
Communication.SendText(s + LineEnding);
}
}
public class ConsoleCommMockDevicePropertiesConfig
{
public string LineEnding { get; set; }
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
public ConsoleCommMockDevicePropertiesConfig()
{
LineEnding = "\x0a";
}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
public class ComPortController : Device, IBasicCommunication
{
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
ComPort Port;
ComPort.ComPortSpec Spec;
public ComPortController(string key, IComPorts ComDevice, uint comPortNum, ComPort.ComPortSpec spec)
: base(key)
{
Port = ComDevice.ComPorts[comPortNum];
Spec = spec;
Debug.Console(2, "Creating com port '{0}'", key);
Debug.Console(2, "Com port spec:\r{0}", JsonConvert.SerializeObject(spec));
}
/// <summary>
/// Creates a ComPort if the parameters are correct. Returns and logs errors if not
/// </summary>
public static ComPortController GetComPortController(string key,
IComPorts comDevice, uint comPortNum, ComPort.ComPortSpec spec)
{
Debug.Console(1, "Creating com port '{0}'", key);
if (comDevice == null)
throw new ArgumentNullException("comDevice");
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException("key");
if (comPortNum > comDevice.NumberOfComPorts)
{
Debug.Console(0, "[{0}] Com port {1} out of range on {2}",
key, comPortNum, comDevice.GetType().Name);
return null;
}
var port = new ComPortController(key, comDevice, comPortNum, spec);
return port;
}
/// <summary>
/// Registers port and sends ComSpec
/// </summary>
/// <returns>false if either register or comspec fails</returns>
public override bool CustomActivate()
{
var result = Port.Register();
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(0, this, "Cannot register Com port: {0}", result);
return false;
}
var specResult = Port.SetComPortSpec(Spec);
if (specResult != 0)
{
Debug.Console(0, this, "Cannot set comspec");
return false;
}
Port.SerialDataReceived += new ComPortDataReceivedEvent(Port_SerialDataReceived);
return true;
}
void Port_SerialDataReceived(ComPort ReceivingComPort, ComPortSerialDataEventArgs args)
{
if (BytesReceived != null)
{
var bytes = Encoding.GetEncoding(28591).GetBytes(args.SerialData);
BytesReceived(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
if(TextReceived != null)
TextReceived(this, new GenericCommMethodReceiveTextArgs(args.SerialData));
}
public override bool Deactivate()
{
return Port.UnRegister() == eDeviceRegistrationUnRegistrationResponse.Success;
}
#region IBasicCommunication Members
public void SendText(string text)
{
Port.Send(text);
}
public void SendBytes(byte[] bytes)
{
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
Port.Send(text);
}
#endregion
}
}

View File

@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public static class IRPortHelper
{
public static string IrDriverPathPrefix
{
get
{
return string.Format(@"\NVRAM\Program{0}\IR\", InitialParametersClass.ApplicationNumber);
}
}
/// <summary>
/// Finds either the ControlSystem or a device controller that contains IR ports and
/// returns a port from the hardware device
/// </summary>
/// <param name="propsToken"></param>
/// <returns>IrPortConfig object. The port and or filename will be empty/null
/// if valid values don't exist on config</returns>
public static IrOutPortConfig GetIrPort(JToken propsToken)
{
var control = propsToken["control"];
if (control == null)
return null;
if (control["method"].Value<string>() != "ir")
{
Debug.Console(0, "IRPortHelper called with non-IR properties");
return null;
}
var port = new IrOutPortConfig();
var portDevKey = control.Value<string>("controlPortDevKey");
var portNum = control.Value<uint>("controlPortNumber");
if (portDevKey == null || portNum == 0)
{
Debug.Console(1, "WARNING: Properties is missing port device or port number");
return port;
}
IIROutputPorts irDev = null;
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
irDev = Global.ControlSystem;
else
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
if (irDev == null)
{
Debug.Console(1, "[Config] Error, device with IR ports '{0}' not found", portDevKey);
return port;
}
if (portNum <= irDev.NumberOfIROutputPorts) // success!
{
var file = IrDriverPathPrefix + control["irFile"].Value<string>();
port.Port = irDev.IROutputPorts[portNum];
port.FileName = file;
return port; // new IrOutPortConfig { Port = irDev.IROutputPorts[portNum], FileName = file };
}
else
{
Debug.Console(1, "[Config] Error, device '{0}' IR port {1} out of range",
portDevKey, portNum);
return port;
}
}
/// <summary>
/// Returns a ready-to-go IrOutputPortController from a DeviceConfig object.
/// </summary>
public static IrOutputPortController GetIrOutputPortController(DeviceConfig devConf)
{
var irControllerKey = devConf.Key + "-ir";
if (devConf.Properties == null)
{
Debug.Console(0, "[{0}] WARNING: Device config does not include properties. IR will not function.", devConf.Key);
return new IrOutputPortController(irControllerKey, null, "");
}
var control = devConf.Properties["control"];
if (control == null)
{
var c = new IrOutputPortController(irControllerKey, null, "");
Debug.Console(0, c, "WARNING: Device config does not include control properties. IR will not function");
return c;
}
var portDevKey = control.Value<string>("controlPortDevKey");
var portNum = control.Value<uint>("controlPortNumber");
IIROutputPorts irDev = null;
if (portDevKey == null)
{
var c = new IrOutputPortController(irControllerKey, null, "");
Debug.Console(0, c, "WARNING: control properties is missing ir device");
return c;
}
if (portNum == 0)
{
var c = new IrOutputPortController(irControllerKey, null, "");
Debug.Console(0, c, "WARNING: control properties is missing ir port number");
return c;
}
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
irDev = Global.ControlSystem;
else
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
if (irDev == null)
{
var c = new IrOutputPortController(irControllerKey, null, "");
Debug.Console(0, c, "WARNING: device with IR ports '{0}' not found", portDevKey);
return c;
}
if (portNum <= irDev.NumberOfIROutputPorts) // success!
return new IrOutputPortController(irControllerKey, irDev.IROutputPorts[portNum],
IrDriverPathPrefix + control["irFile"].Value<string>());
else
{
var c = new IrOutputPortController(irControllerKey, null, "");
Debug.Console(0, c, "WARNING: device '{0}' IR port {1} out of range",
portDevKey, portNum);
return c;
}
}
}
/// <summary>
/// Wrapper to help in IR port creation
/// </summary>
public class IrOutPortConfig
{
public IROutputPort Port { get; set; }
public string FileName { get; set; }
public IrOutPortConfig()
{
FileName = "";
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
//public class ComPortConfig
//{
// //public string ContolPortDevKey { get; set; }
// //public uint ControlPortNumber { get; set; }
// [JsonConverter(typeof(ComSpecJsonConverter))]
// public ComPort.ComPortSpec ComParams { get; set; }
//}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Override this and splice on specific room type behavior, as well as other properties
/// </summary>
public class BasicConfig
{
[JsonProperty("info")]
public InfoConfig Info { get; set; }
//[JsonProperty("roomLists")]
//public Dictionary<string, List<string>> RoomLists { get; set; }
[JsonProperty("devices")]
public List<DeviceConfig> Devices { get; set; }
[JsonProperty("sourceLists")]
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
[JsonProperty("tieLines")]
public List<TieLineConfig> TieLines { get; set; }
/// <summary>
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
/// </summary>
public Dictionary<string, SourceListItem> GetSourceListForKey(string key)
{
if (string.IsNullOrEmpty(key) || !SourceLists.ContainsKey(key))
return null;
return SourceLists[key];
}
}
}

View File

@@ -1,6 +1,4 @@

using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -11,13 +9,10 @@ using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Represents a ConfigPropertiesHelpers
/// </summary>
public class ConfigPropertiesHelpers
{
/// <summary>
/// GetHasAudio method
/// Returns the value of properties.hasAudio, or false if not defined
/// </summary>
public static bool GetHasAudio(DeviceConfig deviceConfig)
{

View File

@@ -1,6 +1,4 @@

using System;
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
@@ -13,73 +11,34 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Represents a DeviceConfig
/// </summary>
public class DeviceConfig
{
/// <summary>
/// Gets or sets the Key
/// </summary>
[JsonProperty("key")]
public string Key { get; set; }
/// <summary>
/// Gets or sets the Uid
/// </summary>
[JsonProperty("uid")]
public int Uid { get; set; }
/// <summary>
/// Gets or sets the Name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the Group
/// </summary>
[JsonProperty("group")]
public string Group { get; set; }
/// <summary>
/// Gets or sets the Type
/// </summary>
[JsonProperty("type")]
public string Type { get; set; }
/// <summary>
/// Gets or sets the Properties
/// </summary>
[JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; }
public DeviceConfig(DeviceConfig dc)
{
Key = dc.Key;
Uid = dc.Uid;
Name = dc.Name;
Group = dc.Group;
Type = dc.Type;
Properties = JToken.Parse(dc.Properties.ToString());
//Properties = JToken.FromObject(dc.Properties);
}
public DeviceConfig() { }
}
/// <summary>
/// Represents a DevicePropertiesConverter
///
/// </summary>
public class DevicePropertiesConverter : JsonConverter
{
/// <summary>
/// CanConvert method
/// </summary>
public override bool CanConvert(Type objectType)
{
return objectType == typeof(JToken);
@@ -90,7 +49,6 @@ namespace PepperDash.Essentials.Core.Config
return JToken.ReadFrom(reader);
}
/// <inheritdoc />
public override bool CanWrite
{
get
@@ -99,10 +57,6 @@ namespace PepperDash.Essentials.Core.Config
}
}
/// <summary>
/// WriteJson method
/// </summary>
/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("SOD OFF HOSER");

View File

@@ -0,0 +1,36 @@
using System;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Represents the info section of a Config file
/// </summary>
public class InfoConfig
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("date")]
public DateTime Date { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("comment")]
public string Comment { get; set; }
public InfoConfig()
{
Name = "";
Date = DateTime.Now;
Type = "";
Version = "";
Comment = "";
}
}
}

View File

@@ -0,0 +1,127 @@
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public static class CommonBoolCue
{
public static readonly Cue Power = new Cue("Power", 101, eCueType.Bool);
public static readonly Cue PowerOn = new Cue("PowerOn", 102, eCueType.Bool);
public static readonly Cue PowerOff = new Cue("PowerOff", 103, eCueType.Bool);
public static readonly Cue HasPowerFeedback = new Cue("HasPowerFeedback", 101, eCueType.Bool);
public static readonly Cue PowerOnFeedback = new Cue("PowerOnFeedback", 102, eCueType.Bool);
public static readonly Cue IsOnlineFeedback = new Cue("IsOnlineFeedback", 104, eCueType.Bool);
public static readonly Cue IsWarmingUp = new Cue("IsWarmingUp", 105, eCueType.Bool);
public static readonly Cue IsCoolingDown = new Cue("IsCoolingDown", 106, eCueType.Bool);
public static readonly Cue Dash = new Cue("Dash", 109, eCueType.Bool);
public static readonly Cue Digit0 = new Cue("Digit0", 110, eCueType.Bool);
public static readonly Cue Digit1 = new Cue("Digit1", 111, eCueType.Bool);
public static readonly Cue Digit2 = new Cue("Digit2", 112, eCueType.Bool);
public static readonly Cue Digit3 = new Cue("Digit3", 113, eCueType.Bool);
public static readonly Cue Digit4 = new Cue("Digit4", 114, eCueType.Bool);
public static readonly Cue Digit5 = new Cue("Digit5", 115, eCueType.Bool);
public static readonly Cue Digit6 = new Cue("Digit6", 116, eCueType.Bool);
public static readonly Cue Digit7 = new Cue("Digit7", 117, eCueType.Bool);
public static readonly Cue Digit8 = new Cue("Digit8", 118, eCueType.Bool);
public static readonly Cue Digit9 = new Cue("Digit9", 119, eCueType.Bool);
public static readonly Cue KeypadMisc1 = new Cue("KeypadMisc1", 120, eCueType.Bool);
public static readonly Cue KeypadMisc2 = new Cue("KeypadMisc2", 121, eCueType.Bool);
public static readonly Cue NumericEnter = new Cue("Enter", 122, eCueType.Bool);
public static readonly Cue ChannelUp = new Cue("ChannelUp", 123, eCueType.Bool);
public static readonly Cue ChannelDown = new Cue("ChannelDown", 124, eCueType.Bool);
public static readonly Cue Last = new Cue("Last", 125, eCueType.Bool);
public static readonly Cue OpenClose = new Cue("OpenClose", 126, eCueType.Bool);
public static readonly Cue Subtitle = new Cue("Subtitle", 127, eCueType.Bool);
public static readonly Cue Audio = new Cue("Audio", 128, eCueType.Bool);
public static readonly Cue Info = new Cue("Info", 129, eCueType.Bool);
public static readonly Cue Menu = new Cue("Menu", 130, eCueType.Bool);
public static readonly Cue DeviceMenu = new Cue("DeviceMenu", 131, eCueType.Bool);
public static readonly Cue Return = new Cue("Return", 132, eCueType.Bool);
public static readonly Cue Back = new Cue("Back", 133, eCueType.Bool);
public static readonly Cue Exit = new Cue("Exit", 134, eCueType.Bool);
public static readonly Cue Clear = new Cue("Clear", 135, eCueType.Bool);
public static readonly Cue List = new Cue("List", 136, eCueType.Bool);
public static readonly Cue Guide = new Cue("Guide", 137, eCueType.Bool);
public static readonly Cue Am = new Cue("Am", 136, eCueType.Bool);
public static readonly Cue Fm = new Cue("Fm", 137, eCueType.Bool);
public static readonly Cue Up = new Cue("Up", 138, eCueType.Bool);
public static readonly Cue Down = new Cue("Down", 139, eCueType.Bool);
public static readonly Cue Left = new Cue("Left", 140, eCueType.Bool);
public static readonly Cue Right = new Cue("Right", 141, eCueType.Bool);
public static readonly Cue Select = new Cue("Select", 142, eCueType.Bool);
public static readonly Cue SmartApps = new Cue("SmartApps", 143, eCueType.Bool);
public static readonly Cue Dvr = new Cue("Dvr", 144, eCueType.Bool);
public static readonly Cue Play = new Cue("Play", 145, eCueType.Bool);
public static readonly Cue Pause = new Cue("Pause", 146, eCueType.Bool);
public static readonly Cue Stop = new Cue("Stop", 147, eCueType.Bool);
public static readonly Cue ChapNext = new Cue("ChapNext", 148, eCueType.Bool);
public static readonly Cue ChapPrevious = new Cue("ChapPrevious", 149, eCueType.Bool);
public static readonly Cue Rewind = new Cue("Rewind", 150, eCueType.Bool);
public static readonly Cue Ffwd = new Cue("Ffwd", 151, eCueType.Bool);
public static readonly Cue Replay = new Cue("Replay", 152, eCueType.Bool);
public static readonly Cue Advance = new Cue("Advance", 153, eCueType.Bool);
public static readonly Cue Record = new Cue("Record", 154, eCueType.Bool);
public static readonly Cue Red = new Cue("Red", 155, eCueType.Bool);
public static readonly Cue Green = new Cue("Green", 156, eCueType.Bool);
public static readonly Cue Yellow = new Cue("Yellow", 157, eCueType.Bool);
public static readonly Cue Blue = new Cue("Blue", 158, eCueType.Bool);
public static readonly Cue Home = new Cue("Home", 159, eCueType.Bool);
public static readonly Cue PopUp = new Cue("PopUp", 160, eCueType.Bool);
public static readonly Cue PageUp = new Cue("PageUp", 161, eCueType.Bool);
public static readonly Cue PageDown = new Cue("PageDown", 162, eCueType.Bool);
public static readonly Cue Search = new Cue("Search", 163, eCueType.Bool);
public static readonly Cue Setup = new Cue("Setup", 164, eCueType.Bool);
public static readonly Cue RStep = new Cue("RStep", 165, eCueType.Bool);
public static readonly Cue FStep = new Cue("FStep", 166, eCueType.Bool);
public static readonly Cue IsConnected = new Cue("IsConnected", 281, eCueType.Bool);
public static readonly Cue IsOk = new Cue("IsOk", 282, eCueType.Bool);
public static readonly Cue InWarning = new Cue("InWarning", 283, eCueType.Bool);
public static readonly Cue InError = new Cue("InError", 284, eCueType.Bool);
public static readonly Cue StatusUnknown = new Cue("StatusUnknown", 285, eCueType.Bool);
public static readonly Cue VolumeUp = new Cue("VolumeUp", 401, eCueType.Bool);
public static readonly Cue VolumeDown = new Cue("VolumeDown", 402, eCueType.Bool);
public static readonly Cue MuteOn = new Cue("MuteOn", 403, eCueType.Bool);
public static readonly Cue MuteOff = new Cue("MuteOff", 404, eCueType.Bool);
public static readonly Cue MuteToggle = new Cue("MuteToggle", 405, eCueType.Bool);
public static readonly Cue ShowVolumeButtons = new Cue("ShowVolumeButtons", 406, eCueType.Bool);
public static readonly Cue ShowVolumeSlider = new Cue("ShowVolumeSlider", 407, eCueType.Bool);
public static readonly Cue Hdmi1 = new Cue("Hdmi1", 451, eCueType.Bool);
public static readonly Cue Hdmi2 = new Cue("Hdmi2", 452, eCueType.Bool);
public static readonly Cue Hdmi3 = new Cue("Hdmi3", 453, eCueType.Bool);
public static readonly Cue Hdmi4 = new Cue("Hdmi4", 454, eCueType.Bool);
public static readonly Cue Hdmi5 = new Cue("Hdmi5", 455, eCueType.Bool);
public static readonly Cue Hdmi6 = new Cue("Hdmi6", 456, eCueType.Bool);
public static readonly Cue DisplayPort1 = new Cue("DisplayPort1", 457, eCueType.Bool);
public static readonly Cue DisplayPort2 = new Cue("DisplayPort2", 458, eCueType.Bool);
public static readonly Cue Dvi1 = new Cue("Dvi1", 459, eCueType.Bool);
public static readonly Cue Dvi2 = new Cue("Dvi2", 460, eCueType.Bool);
public static readonly Cue Video1 = new Cue("Video1", 461, eCueType.Bool);
public static readonly Cue Video2 = new Cue("Video2", 462, eCueType.Bool);
public static readonly Cue Component1 = new Cue("Component1", 463, eCueType.Bool);
public static readonly Cue Component2 = new Cue("Component2", 464, eCueType.Bool);
public static readonly Cue Vga1 = new Cue("Vga1", 465, eCueType.Bool);
public static readonly Cue Vga2 = new Cue("Vga2", 466, eCueType.Bool);
public static readonly Cue Rgb1 = new Cue("Rgb1", 467, eCueType.Bool);
public static readonly Cue Rgb2 = new Cue("Rgb2", 468, eCueType.Bool);
public static readonly Cue Antenna = new Cue("Antenna", 469, eCueType.Bool);
public static readonly Cue InCall = new Cue("InCall", 501, eCueType.Bool);
}
public static class CommonIntCue
{
public static readonly Cue MainVolumeLevel = new Cue("MainVolumeLevel", 401, eCueType.Int);
public static readonly Cue MainVolumeLevelFeedback = new Cue("MainVolumeLevelFeedback", 401, eCueType.Int);
}
public static class CommonStringCue
{
public static readonly Cue IpConnectionsText = new Cue("IpConnectionsText", 9999, eCueType.String);
}
}

View File

@@ -1,128 +1,122 @@
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; }
public BoolFeedback IsOnline { get; private set; }
public BoolFeedback IsRegistered { get; private set; }
public StringFeedback IpConnectionsText { get; private set; }
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
: base(key, name)
{
Hardware = hardware;
IsOnline = new BoolFeedback(CommonBoolCue.IsOnlineFeedback, () => Hardware.IsOnline);
IsRegistered = new BoolFeedback(new Cue("IsRegistered", 0, eCueType.Bool), () => Hardware.Registered);
IpConnectionsText = new StringFeedback(CommonStringCue.IpConnectionsText, () =>
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
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.LogMessage(LogEventLevel.Information, this, "Activating");
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
<<<<<<< HEAD
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
=======
Debug.LogMessage(LogEventLevel.Information, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
>>>>>>> origin/feature/ecs-342-neil
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>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
IsOnline,
IsRegistered,
IpConnectionsText
};
}
}
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
IsOnline.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();
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.LogMessage(LogEventLevel.Information, "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; }
public BoolFeedback IsOnline { get; private set; }
public BoolFeedback IsRegistered { get; private set; }
public StringFeedback IpConnectionsText { get; private set; }
public CrestronGenericBaseDevice(string key, string name, GenericBase hardware)
: base(key, name)
{
Hardware = hardware;
IsOnline = new BoolFeedback(CommonBoolCue.IsOnlineFeedback, () => Hardware.IsOnline);
IsRegistered = new BoolFeedback(new Cue("IsRegistered", 0, eCueType.Bool), () => Hardware.Registered);
IpConnectionsText = new StringFeedback(CommonStringCue.IpConnectionsText, () =>
string.Join(",", Hardware.ConnectedIpList.Select(cip => cip.DeviceIpAddress).ToArray()));
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()
{
new CTimer(o =>
{
Debug.Console(1, this, "Activating");
var response = Hardware.RegisterWithLogging(Key);
if (response == eDeviceRegistrationUnRegistrationResponse.Success)
{
Hardware.OnlineStatusChange += new OnlineStatusChangeEventHandler(Hardware_OnlineStatusChange);
CommunicationMonitor.Start();
}
}, 0);
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>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
IsOnline,
IsRegistered,
IpConnectionsText
};
}
}
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
IsOnline.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();
if (result != eDeviceRegistrationUnRegistrationResponse.Success)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot register device '{0}': {1}", key, result);
}
return result;
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Encapsulates a string-named, joined and typed command to a device
/// </summary>
[Obsolete()]
public class DevAction
{
public Cue Cue { get; private set; }
public Action<object> Action { get; private set; }
public DevAction(Cue cue, Action<object> action)
{
Cue = cue;
Action = action;
}
}
public enum eCueType
{
Bool, Int, String, Void, Other
}
/// <summary>
/// The Cue class is a container to represent a name / join number / type for simplifying
/// commands coming into devices.
/// </summary>
public class Cue
{
public string Name { get; private set; }
public uint Number { get; private set; }
public eCueType Type { get; private set; }
public Cue(string name, uint join, eCueType type)
{
Name = name;
Number = join;
Type = type;
}
/// <summary>
/// Override that prints out the cue's data
/// </summary>
public override string ToString()
{
return string.Format("{0} Cue '{1}'-{2}", Type, Name, Number);
}
///// <summary>
///// Returns a new Cue with JoinNumber offset
///// </summary>
//public Cue GetOffsetCopy(uint offset)
//{
// return new Cue(Name, Number + offset, Type);
//}
/// <summary>
/// Helper method to create a Cue of Bool type
/// </summary>
/// <returns>Cue</returns>
public static Cue BoolCue(string name, uint join)
{
return new Cue(name, join, eCueType.Bool);
}
/// <summary>
/// Helper method to create a Cue of ushort type
/// </summary>
/// <returns>Cue</returns>
public static Cue UShortCue(string name, uint join)
{
return new Cue(name, join, eCueType.Int);
}
/// <summary>
/// Helper method to create a Cue of string type
/// </summary>
/// <returns>Cue</returns>
public static Cue StringCue(string name, uint join)
{
return new Cue(name, join, eCueType.String);
}
public static readonly Cue DefaultBoolCue = new Cue("-none-", 0, eCueType.Bool);
public static readonly Cue DefaultIntCue = new Cue("-none-", 0, eCueType.Int);
public static readonly Cue DefaultStringCue = new Cue("-none-", 0, eCueType.String);
}
}

View File

@@ -0,0 +1,142 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharp.CrestronDataStore;
//using Crestron.SimplSharpPro;
//namespace PepperDash.Essentials.Core
//{
// public class Debug
// {
// public static uint Level { get; private set; }
// /// <summary>
// /// This should called from the ControlSystem Initiailize method.
// /// </summary>
// public static void Initialize()
// {
// // Add command to console
// CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
// "appdebug:P [0-2]: Sets the application's console debug message level",
// ConsoleAccessLevelEnum.AccessOperator);
// uint level = 0;
// var err = CrestronDataStoreStatic.GetGlobalUintValue("DebugLevel", out level);
// if (err == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
// SetDebugLevel(level);
// else if (err == CrestronDataStore.CDS_ERROR.CDS_RECORD_NOT_FOUND)
// CrestronDataStoreStatic.SetGlobalUintValue("DebugLevel", 0);
// else
// CrestronConsole.PrintLine("Error restoring console debug level setting: {0}", err);
// }
// /// <summary>
// /// Callback for console command
// /// </summary>
// /// <param name="levelString"></param>
// public static void SetDebugFromConsole(string levelString)
// {
// try
// {
// if (string.IsNullOrEmpty(levelString.Trim()))
// {
// CrestronConsole.PrintLine("AppDebug level = {0}", Level);
// return;
// }
// SetDebugLevel(Convert.ToUInt32(levelString));
// }
// catch
// {
// CrestronConsole.PrintLine("Usage: appdebug:P [0-2]");
// }
// }
// /// <summary>
// /// Sets the debug level
// /// </summary>
// /// <param name="level"> Valid values 0 (no debug), 1 (critical), 2 (all messages)</param>
// public static void SetDebugLevel(uint level)
// {
// if (level <= 2)
// {
// Level = 2;
// CrestronConsole.PrintLine("[Application {0}], Debug level set to {1}",
// InitialParametersClass.ApplicationNumber, level);
// var err = CrestronDataStoreStatic.SetGlobalUintValue("DebugLevel", level);
// if(err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
// CrestronConsole.PrintLine("Error saving console debug level setting: {0}", err);
// }
// }
// /// <summary>
// /// Prints message to console if current debug level is equal to or higher than the level of this message.
// /// Uses CrestronConsole.PrintLine.
// /// </summary>
// /// <param name="level"></param>
// /// <param name="format">Console format string</param>
// /// <param name="items">Object parameters</param>
// public static void Console(uint level, string format, params object[] items)
// {
// if (Level >= level)
// CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber,
// string.Format(format, items));
// }
// /// <summary>
// /// Appends a device Key to the beginning of a message
// /// </summary>
// public static void Console(uint level, IKeyed dev, string format, params object[] items)
// {
// if (Level >= level)
// Console(level, "[{0}] {1}", dev.Key, string.Format(format, items));
// }
// public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
// string format, params object[] items)
// {
// if (Level >= level)
// {
// var str = string.Format("[{0}] {1}", dev.Key, string.Format(format, items));
// Console(level, str);
// LogError(errorLogLevel, str);
// }
// }
// public static void Console(uint level, ErrorLogLevel errorLogLevel,
// string format, params object[] items)
// {
// if (Level >= level)
// {
// var str = string.Format(format, items);
// Console(level, str);
// LogError(errorLogLevel, str);
// }
// }
// public static void LogError(ErrorLogLevel errorLogLevel, string str)
// {
// string msg = string.Format("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
// switch (errorLogLevel)
// {
// case ErrorLogLevel.Error:
// ErrorLog.Error(msg);
// break;
// case ErrorLogLevel.Warning:
// ErrorLog.Warn(msg);
// break;
// case ErrorLogLevel.Notice:
// ErrorLog.Notice(msg);
// break;
// }
// }
// public enum ErrorLogLevel
// {
// Error, Warning, Notice, None
// }
// }
//}

View File

@@ -24,9 +24,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
public static class IChannelExtensions
{
/// <summary>
/// LinkButtons method
/// </summary>
public static void LinkButtons(this IChannel dev, BasicTriList triList)
{
triList.SetBoolSigAction(123, dev.ChannelUp);
@@ -37,9 +34,6 @@ namespace PepperDash.Essentials.Core
triList.SetBoolSigAction(134, dev.Exit);
}
/// <summary>
/// UnlinkButtons method
/// </summary>
public static void UnlinkButtons(this IChannel dev, BasicTriList triList)
{
triList.ClearBoolSigAction(123);

View File

@@ -22,9 +22,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
public static class IColorExtensions
{
/// <summary>
/// LinkButtons method
/// </summary>
public static void LinkButtons(this IColor dev, BasicTriList TriList)
{
TriList.SetBoolSigAction(155, dev.Red);
@@ -33,9 +30,6 @@ namespace PepperDash.Essentials.Core
TriList.SetBoolSigAction(158, dev.Blue);
}
/// <summary>
/// UnlinkButtons method
/// </summary>
public static void UnlinkButtons(this IColor dev, BasicTriList triList)
{
triList.ClearBoolSigAction(155);

View File

@@ -1,56 +1,50 @@
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public interface IDPad : IKeyed
{
void Up(bool pressRelease);
void Down(bool pressRelease);
void Left(bool pressRelease);
void Right(bool pressRelease);
void Select(bool pressRelease);
void Menu(bool pressRelease);
void Exit(bool pressRelease);
}
/// <summary>
///
/// </summary>
public static class IDPadExtensions
{
/// <summary>
/// LinkButtons method
/// </summary>
public static void LinkButtons(this IDPad dev, BasicTriList triList)
{
triList.SetBoolSigAction(138, dev.Up);
triList.SetBoolSigAction(139, dev.Down);
triList.SetBoolSigAction(140, dev.Left);
triList.SetBoolSigAction(141, dev.Right);
triList.SetBoolSigAction(142, dev.Select);
triList.SetBoolSigAction(130, dev.Menu);
triList.SetBoolSigAction(134, dev.Exit);
}
/// <summary>
/// UnlinkButtons method
/// </summary>
public static void UnlinkButtons(this IDPad dev, BasicTriList triList)
{
triList.ClearBoolSigAction(138);
triList.ClearBoolSigAction(139);
triList.ClearBoolSigAction(140);
triList.ClearBoolSigAction(141);
triList.ClearBoolSigAction(142);
triList.ClearBoolSigAction(130);
triList.ClearBoolSigAction(134);
}
}
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public interface IDPad
{
void Up(bool pressRelease);
void Down(bool pressRelease);
void Left(bool pressRelease);
void Right(bool pressRelease);
void Select(bool pressRelease);
void Menu(bool pressRelease);
void Exit(bool pressRelease);
}
/// <summary>
///
/// </summary>
public static class IDPadExtensions
{
public static void LinkButtons(this IDPad dev, BasicTriList triList)
{
triList.SetBoolSigAction(138, dev.Up);
triList.SetBoolSigAction(139, dev.Down);
triList.SetBoolSigAction(140, dev.Left);
triList.SetBoolSigAction(141, dev.Right);
triList.SetBoolSigAction(142, dev.Select);
triList.SetBoolSigAction(130, dev.Menu);
triList.SetBoolSigAction(134, dev.Exit);
}
public static void UnlinkButtons(this IDPad dev, BasicTriList triList)
{
triList.ClearBoolSigAction(138);
triList.ClearBoolSigAction(139);
triList.ClearBoolSigAction(140);
triList.ClearBoolSigAction(141);
triList.ClearBoolSigAction(142);
triList.ClearBoolSigAction(130);
triList.ClearBoolSigAction(134);
}
}
}

View File

@@ -0,0 +1,13 @@
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IPower, ITransport, IUiDisplayInfo
{
}
}

View File

@@ -6,9 +6,6 @@ using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core.Devices.DeviceTypeInterfaces
{
/// <summary>
/// Defines the contract for IDisplayBasic
/// </summary>
public interface IDisplayBasic
{
void InputHdmi1();

View File

@@ -6,9 +6,6 @@ using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for IDumbSource
/// </summary>
public interface IDumbSource
{
}

View File

@@ -25,9 +25,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
public static class IDvrExtensions
{
/// <summary>
/// LinkButtons method
/// </summary>
public static void LinkButtons(this IDvr dev, BasicTriList triList)
{
triList.SetBoolSigAction(136, dev.DvrList);

View File

@@ -1,14 +1,14 @@
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for INumericKeypad
/// </summary>
public interface INumericKeypad:IKeyed
/// <summary>
///
/// </summary>
public interface INumericKeypad
{
void Digit0(bool pressRelease);
void Digit1(bool pressRelease);
@@ -65,9 +65,6 @@ namespace PepperDash.Essentials.Core
trilist.StringInput[111].StringValue = dev.KeypadAccessoryButton2Label;
}
/// <summary>
/// UnlinkButtons method
/// </summary>
public static void UnlinkButtons(this INumericKeypad dev, BasicTriList trilist)
{
trilist.ClearBoolSigAction(110);

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.Fusion;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public interface IPower
{
void PowerOn();
void PowerOff();
void PowerToggle();
BoolFeedback PowerIsOnFeedback { get; }
}
/// <summary>
///
/// </summary>
public static class IPowerExtensions
{
public static void LinkButtons(this IPower dev, BasicTriList triList)
{
triList.SetSigFalseAction(101, dev.PowerOn);
triList.SetSigFalseAction(102, dev.PowerOff);
triList.SetSigFalseAction(103, dev.PowerToggle);
dev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
}
public static void UnlinkButtons(this IPower dev, BasicTriList triList)
{
triList.ClearBoolSigAction(101);
triList.ClearBoolSigAction(102);
triList.ClearBoolSigAction(103);
dev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
}
}
}

View File

@@ -5,9 +5,9 @@ using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for ISetTopBoxControls
/// </summary>
/// <summary>
///
/// </summary>
public interface ISetTopBoxControls : IChannel, IColor, IDPad, ISetTopBoxNumericKeypad,
ITransport, IUiDisplayInfo
{
@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
bool HasDpad { get; }
PepperDash.Essentials.Core.Presets.DevicePresetsModel TvPresets { get; }
PepperDash.Essentials.Core.Presets.DevicePresetsModel PresetsModel { get; }
void LoadPresets(string filePath);
void DvrList(bool pressRelease);
@@ -40,18 +40,12 @@ namespace PepperDash.Essentials.Core
public static class ISetTopBoxControlsExtensions
{
/// <summary>
/// LinkButtons method
/// </summary>
public static void LinkButtons(this ISetTopBoxControls dev, BasicTriList triList)
{
triList.SetBoolSigAction(136, dev.DvrList);
triList.SetBoolSigAction(152, dev.Replay);
}
/// <summary>
/// UnlinkButtons method
/// </summary>
public static void UnlinkButtons(this ISetTopBoxControls dev, BasicTriList triList)
{
triList.ClearBoolSigAction(136);

View File

@@ -2,9 +2,9 @@
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for ITransport
/// </summary>
/// <summary>
///
/// </summary>
public interface ITransport
{
void Play(bool pressRelease);
@@ -38,9 +38,6 @@ namespace PepperDash.Essentials.Core
triList.SetBoolSigAction(154, dev.Record);
}
/// <summary>
/// UnlinkButtons method
/// </summary>
public static void UnlinkButtons(this ITransport dev, BasicTriList triList)
{
triList.ClearBoolSigAction(145);

View File

@@ -2,9 +2,9 @@
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for IUiDisplayInfo
/// </summary>
/// <summary>
/// Describes things needed to show on UI
/// </summary>
public interface IUiDisplayInfo : IKeyed
{
uint DisplayUiType { get; }

View File

@@ -1,46 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Adds control of codec receive volume
/// </summary>
public interface IReceiveVolume
{
// Break this out into 3 interfaces
void SetReceiveVolume(ushort level);
void ReceiveMuteOn();
void ReceiveMuteOff();
void ReceiveMuteToggle();
IntFeedback ReceiveLevelFeedback { get; }
BoolFeedback ReceiveMuteIsOnFeedback { get; }
}
/// <summary>
/// Defines the contract for ITransmitVolume
/// </summary>
public interface ITransmitVolume
{
void SetTransmitVolume(ushort level);
void TransmitMuteOn();
void TransmitMuteOff();
void TransmitMuteToggle();
IntFeedback TransmitLevelFeedback { get; }
BoolFeedback TransmitMuteIsOnFeedback { get; }
}
/// <summary>
/// Defines the contract for IPrivacy
/// </summary>
public interface IPrivacy
{
void PrivacyModeOn();
void PrivacyModeOff();
void PrivacyModeToggle();
BoolFeedback PrivacyModeIsOnFeedback { get; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Adds control of codec receive volume
/// </summary>
public interface IReceiveVolume
{
// Break this out into 3 interfaces
void SetReceiveVolume(ushort level);
void ReceiveMuteOn();
void ReceiveMuteOff();
void ReceiveMuteToggle();
IntFeedback ReceiveLevelFeedback { get; }
BoolFeedback ReceiveMuteIsOnFeedback { get; }
}
/// <summary>
/// Adds control of codec transmit volume
/// </summary>
public interface ITransmitVolume
{
void SetTransmitVolume(ushort level);
void TransmitMuteOn();
void TransmitMuteOff();
void TransmitMuteToggle();
IntFeedback TransmitLevelFeedback { get; }
BoolFeedback TransmitMuteIsOnFeedback { get; }
}
/// <summary>
/// Adds control of codec privacy function (microphone mute)
/// </summary>
public interface IPrivacy
{
void PrivacyModeOn();
void PrivacyModeOff();
void PrivacyModeToggle();
BoolFeedback PrivacyModeIsOnFeedback { get; }
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Requirements for a device that has dialing capabilities
/// </summary>
public interface IHasDialer
{
// Add requirements for Dialer functionality
void Dial(string number);
<<<<<<< HEAD
void EndCall(string number);
=======
void EndCall(object activeCall);
void EndAllCalls();
>>>>>>> origin/feature/cisco-spark-2
void AcceptCall();
void RejectCall();
void SendDtmf(string digit);
IntFeedback ActiveCallCountFeedback { get; }
BoolFeedback IncomingCallFeedback { get; }
}
/// <summary>
/// Defines minimum volume controls for a codec device with dialing capabilities
/// </summary>
public interface ICodecAudio : IBasicVolumeWithFeedback, IPrivacy
{
}
/// <summary>
/// Adds control of codec receive volume
/// </summary>
public interface IReceiveVolume
{
// Break this out into 3 interfaces
void SetReceiveVolume(ushort level);
void ReceiveMuteOn();
void ReceiveMuteOff();
void ReceiveMuteToggle();
IntFeedback ReceiveLevelFeedback { get; }
BoolFeedback ReceiveMuteIsOnFeedback { get; }
}
/// <summary>
/// Adds control of codec transmit volume
/// </summary>
public interface ITransmitVolume
{
void SetTransmitVolume(ushort level);
void TransmitMuteOn();
void TransmitMuteOff();
void TransmitMuteToggle();
IntFeedback TransmitLevelFeedback { get; }
BoolFeedback TransmitMuteIsOnFeedback { get; }
}
/// <summary>
/// Adds control of codec privacy function (microphone mute)
/// </summary>
public interface IPrivacy
{
void PrivacyModeOn();
void PrivacyModeOff();
void PrivacyModeToggle();
BoolFeedback PrivacyModeIsOnFeedback { get; }
}
public interface IHasCallHistory
{
// Add recent calls list
}
public interface IHasDirectory
{
}
public interface IHasObtp
{
// Upcoming Meeting warning event
}
}

View File

@@ -0,0 +1,294 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using Newtonsoft.Json;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class DeviceJsonApi
{
/// <summary>
///
/// </summary>
/// <param name="json"></param>
public static void DoDeviceActionWithJson(string json)
{
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
DoDeviceAction(action);
}
/// <summary>
///
/// </summary>
/// <param name="action"></param>
public static void DoDeviceAction(DeviceActionWrapper action)
{
var key = action.DeviceKey;
var obj = FindObjectOnPath(key);
if (obj == null)
return;
CType t = obj.GetType();
var method = t.GetMethod(action.MethodName);
if (method == null)
{
Debug.Console(0, "Method '{0}' not found", action.MethodName);
return;
}
var mParams = method.GetParameters();
// Add empty params if not provided
if (action.Params == null) action.Params = new object[0];
if (mParams.Length > action.Params.Length)
{
Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length);
return;
}
object[] convertedParams = mParams
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
System.Globalization.CultureInfo.InvariantCulture))
.ToArray();
object ret = method.Invoke(obj, convertedParams);
//Debug.Console(0, JsonConvert.SerializeObject(ret));
// return something?
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetProperties(string deviceObjectPath)
{
var obj = FindObjectOnPath(deviceObjectPath);
if (obj == null)
return "{ \"error\":\"No Device\"}";
CType t = obj.GetType();
// get the properties and set them into a new collection of NameType wrappers
var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
return JsonConvert.SerializeObject(props, Formatting.Indented);
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetMethods(string deviceObjectPath)
{
var obj = FindObjectOnPath(deviceObjectPath);
if (obj == null)
return "{ \"error\":\"No Device\"}";
// Package up method names using helper objects
CType t = obj.GetType();
var methods = t.GetMethods()
.Where(m => !m.IsSpecialName)
.Select(p => new MethodNameParams(p));
return JsonConvert.SerializeObject(methods, Formatting.Indented);
}
public static string GetApiMethods(string deviceObjectPath)
{
var obj = FindObjectOnPath(deviceObjectPath);
if (obj == null)
return "{ \"error\":\"No Device\"}";
// Package up method names using helper objects
CType t = obj.GetType();
var methods = t.GetMethods()
.Where(m => !m.IsSpecialName)
.Where(m => m.GetCustomAttributes(typeof(ApiAttribute), true).Any())
.Select(p => new MethodNameParams(p));
return JsonConvert.SerializeObject(methods, Formatting.Indented);
}
/// <summary>
/// Walks down a dotted object path, starting with a Device, and returns the object
/// at the end of the path
/// </summary>
public static object FindObjectOnPath(string deviceObjectPath)
{
var path = deviceObjectPath.Split('.');
var dev = DeviceManager.GetDeviceForKey(path[0]);
if (dev == null)
{
Debug.Console(0, "Device {0} not found", path[0]);
return null;
}
// loop through any dotted properties
object obj = dev;
if (path.Length > 1)
{
for (int i = 1; i < path.Length; i++)
{
var objName = path[i];
string indexStr = null;
var indexOpen = objName.IndexOf('[');
if (indexOpen != -1)
{
var indexClose = objName.IndexOf(']');
if (indexClose == -1)
{
Debug.Console(0, dev, "ERROR Unmatched index brackets");
return null;
}
// Get the index and strip quotes if any
indexStr = objName.Substring(indexOpen + 1, indexClose - indexOpen - 1).Replace("\"", "");
objName = objName.Substring(0, indexOpen);
Debug.Console(0, dev, " Checking for collection '{0}', index '{1}'", objName, indexStr);
}
CType oType = obj.GetType();
var prop = oType.GetProperty(objName);
if (prop == null)
{
Debug.Console(0, dev, "Property {0} not found on {1}", objName, path[i - 1]);
return null;
}
// if there's an index, try to get the property
if (indexStr != null)
{
if (!typeof(ICollection).IsAssignableFrom(prop.PropertyType))
{
Debug.Console(0, dev, "Property {0} is not collection", objName);
return null;
}
var collection = prop.GetValue(obj, null) as ICollection;
// Get the indexed items "property"
var indexedPropInfo = prop.PropertyType.GetProperty("Item");
// These are the parameters for the indexing. Only care about one
var indexParams = indexedPropInfo.GetIndexParameters();
if (indexParams.Length > 0)
{
Debug.Console(0, " Indexed, param type: {0}", indexParams[0].ParameterType.Name);
var properParam = Convert.ChangeType(indexStr, indexParams[0].ParameterType,
System.Globalization.CultureInfo.InvariantCulture);
try
{
obj = indexedPropInfo.GetValue(collection, new object[] { properParam });
}
// if the index is bad, catch it here.
catch (Crestron.SimplSharp.Reflection.TargetInvocationException e)
{
if (e.InnerException is ArgumentOutOfRangeException)
Debug.Console(0, " Index Out of range");
else if (e.InnerException is KeyNotFoundException)
Debug.Console(0, " Key not found");
return null;
}
}
}
else
obj = prop.GetValue(obj, null);
}
}
return obj;
}
/// <summary>
/// Sets a property on an object.
/// </summary>
/// <param name="deviceObjectPath"></param>
/// <returns></returns>
public static string SetProperty(string deviceObjectPath)
{
throw new NotImplementedException("This could be really useful. Finish it please");
//var obj = FindObjectOnPath(deviceObjectPath);
//if (obj == null)
// return "{\"error\":\"No object found\"}";
//CType t = obj.GetType();
//// get the properties and set them into a new collection of NameType wrappers
//var props = t.GetProperties().Select(p => new PropertyNameType(p, obj));
//return JsonConvert.SerializeObject(props, Formatting.Indented);
}
}
public class DeviceActionWrapper
{
public string DeviceKey { get; set; }
public string MethodName { get; set; }
public object[] Params { get; set; }
}
public class PropertyNameType
{
object Parent;
[JsonIgnore]
public PropertyInfo PropInfo { get; private set; }
public string Name { get { return PropInfo.Name; } }
public string Type { get { return PropInfo.PropertyType.Name; } }
public string Value { get
{
if (PropInfo.CanRead)
{
try
{
return PropInfo.GetValue(Parent, null).ToString();
}
catch (Exception)
{
return null;
}
}
else
return null;
} }
public bool CanRead { get { return PropInfo.CanRead; } }
public bool CanWrite { get { return PropInfo.CanWrite; } }
public PropertyNameType(PropertyInfo info, object parent)
{
PropInfo = info;
Parent = parent;
}
}
public class MethodNameParams
{
[JsonIgnore]
public MethodInfo MethodInfo { get; private set; }
public string Name { get { return MethodInfo.Name; } }
public IEnumerable<NameType> Params { get {
return MethodInfo.GetParameters().Select(p =>
new NameType { Name = p.Name, Type = p.ParameterType.Name });
} }
public MethodNameParams(MethodInfo info)
{
MethodInfo = info;
}
}
public class NameType
{
public string Name { get; set; }
public string Type { get; set; }
}
[AttributeUsage(AttributeTargets.All)]
public class ApiAttribute : CAttribute
{
}
}

View File

@@ -0,0 +1,236 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using Crestron.SimplSharpPro.UI;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public static class DeviceManager
{
//public static List<Device> Devices { get { return _Devices; } }
//static List<Device> _Devices = new List<Device>();
static Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Returns a copy of all the devices in a list
/// </summary>
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
public static void Initialize(CrestronControlSystem cs)
{
//CrestronConsole.AddNewConsoleCommand(ListDeviceCommands, "devcmdlist", "Lists commands",
// ConsoleAccessLevelEnum.AccessOperator);
//CrestronConsole.AddNewConsoleCommand(DoDeviceCommand, "devcmd", "Runs a command on device - key Name value",
// ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s));
}, "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s));
}, "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s));
}, "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
}
/// <summary>
/// Calls activate on all Device class items
/// </summary>
public static void ActivateAll()
{
foreach (var d in Devices.Values)
{
if (d is Device)
(d as Device).Activate();
}
}
/// <summary>
/// Calls activate on all Device class items
/// </summary>
public static void DeactivateAll()
{
foreach (var d in Devices.Values)
{
if (d is Device)
(d as Device).Deactivate();
}
}
//static void ListMethods(string devKey)
//{
// var dev = GetDeviceForKey(devKey);
// if(dev != null)
// {
// var type = dev.GetType().GetCType();
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
// var sb = new StringBuilder();
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
// foreach (var m in methods)
// {
// sb.Append(string.Format("{0}(", m.Name));
// var pars = m.GetParameters();
// foreach (var p in pars)
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
// sb.AppendLine(")");
// }
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
// }
//}
static void ListDevices(string s)
{
Debug.Console(0, "{0} Devices registered with Device Mangager:",Devices.Count);
var sorted = Devices.Values.ToList();
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
foreach (var d in sorted)
{
var name = d is IKeyName ? (d as IKeyName).Name : "---";
Debug.Console(0, " [{0}] {1}", d.Key, name);
}
}
static void ListDeviceFeedbacks(string devKey)
{
var dev = GetDeviceForKey(devKey);
if(dev == null)
{
Debug.Console(0, "Device '{0}' not found", devKey);
return;
}
var statusDev = dev as IHasFeedback;
if(statusDev == null)
{
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
return;
}
statusDev.DumpFeedbacksToConsole(true);
}
//static void ListDeviceCommands(string devKey)
//{
// var dev = GetDeviceForKey(devKey);
// if (dev == null)
// {
// Debug.Console(0, "Device '{0}' not found", devKey);
// return;
// }
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
//}
static void ListDeviceCommStatuses(string input)
{
var sb = new StringBuilder();
foreach (var dev in Devices.Values)
{
if (dev is ICommunicationMonitor)
sb.Append(string.Format("{0}: {1}\r", dev.Key, (dev as ICommunicationMonitor).CommunicationMonitor.Status));
}
CrestronConsole.ConsoleCommandResponse(sb.ToString());
}
//static void DoDeviceCommand(string command)
//{
// Debug.Console(0, "Not yet implemented. Stay tuned");
//}
public static void AddDevice(IKeyed newDev)
{
// Check for device with same key
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
////// If it exists, remove or warn??
//if (existingDevice != null)
if(Devices.ContainsKey(newDev.Key))
{
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
return;
}
Devices.Add(newDev.Key, newDev);
//if (!(_Devices.Contains(newDev)))
// _Devices.Add(newDev);
}
public static void RemoveDevice(IKeyed newDev)
{
if(newDev == null)
return;
if (Devices.ContainsKey(newDev.Key))
Devices.Remove(newDev.Key);
//if (_Devices.Contains(newDev))
// _Devices.Remove(newDev);
else
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
}
public static IEnumerable<string> GetDeviceKeys()
{
//return _Devices.Select(d => d.Key).ToList();
return Devices.Keys;
}
public static IEnumerable<IKeyed> GetDevices()
{
//return _Devices.Select(d => d.Key).ToList();
return Devices.Values;
}
public static IKeyed GetDeviceForKey(string key)
{
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
if (key != null && Devices.ContainsKey(key))
return Devices[key];
return null;
}
/// <summary>
/// Console handler that simulates com port data receive
/// </summary>
/// <param name="s"></param>
public static void SimulateComReceiveOnDevice(string s)
{
// devcomsim:1 xyzabc
var match = Regex.Match(s, @"(\S*)\s*(.*)");
if (match.Groups.Count < 3)
{
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
return;
}
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
ComPortController com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
if (com == null)
{
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
return;
}
com.SimulateReceive(match.Groups[2].Value);
}
}
}

View File

@@ -0,0 +1,56 @@
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
{
public interface IOnline
{
BoolFeedback IsOnline { get; }
}
///// <summary>
///// ** WANT THIS AND ALL ITS FRIENDS TO GO AWAY **
///// Defines a class that has a list of CueAction objects, typically
///// for linking functions to user interfaces or API calls
///// </summary>
//public interface IHasCueActionList
//{
// List<CueActionPair> CueActionList { get; }
//}
//public interface IHasComPortsHardware
//{
// IComPorts ComPortsDevice { get; }
//}
/// <summary>
/// Describes a device that can have a video sync providing device attached to it
/// </summary>
public interface IAttachVideoStatus : IKeyed
{
// Extension methods will depend on this
}
/// <summary>
/// For display classes that can provide usage data
/// </summary>
public interface IDisplayUsage
{
IntFeedback LampHours { get; }
}
public interface IMakeModel : IKeyed
{
string DeviceMake { get; }
string DeviceModel { get; }
}
}

View File

@@ -5,21 +5,14 @@ using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.Core.Devices
{
/// <summary>
/// Represents a GenericCommunicationMonitoredDevice
/// </summary>
public class GenericCommunicationMonitoredDevice : Device, ICommunicationMonitor
{
IBasicCommunication Client;
/// <summary>
/// Gets or sets the CommunicationMonitor
/// </summary>
public StatusMonitorBase CommunicationMonitor { get; private set; }
public GenericCommunicationMonitoredDevice(string key, string name, IBasicCommunication comm, string pollString,
@@ -32,7 +25,7 @@ namespace PepperDash.Essentials.Core.Devices
// ------------------------------------------------------DELETE THIS
CommunicationMonitor.StatusChange += (o, a) =>
{
Debug.LogMessage(LogEventLevel.Verbose, this, "Communication monitor status change: {0}", a.Status);
Debug.Console(2, this, "Communication monitor status change: {0}", a.Status);
};
}
@@ -42,19 +35,41 @@ namespace PepperDash.Essentials.Core.Devices
{
}
/// <summary>
/// CustomActivate method
/// </summary>
/// <inheritdoc />
/// <summary>
/// Generic monitor for TCP reachability. Default with 30s poll, 120s warning and 300s error times
/// </summary>
[Obsolete]
public GenericCommunicationMonitoredDevice(string key, string name, string hostname, int port, string pollString)
: this(key, name, hostname, port, pollString, 30000, 120000, 300000)
{
}
/// <summary>
/// Monitor for TCP reachability
/// </summary>
[Obsolete]
public GenericCommunicationMonitoredDevice(string key, string name, string hostname, int port, string pollString,
long pollTime, long warningTime, long errorTime)
: base(key, name)
{
Client = new GenericTcpIpClient(key + "-tcp", hostname, port, 512);
CommunicationMonitor = new GenericCommunicationMonitor(this, Client, pollTime, warningTime, errorTime, pollString);
// ------------------------------------------------------DELETE THIS
CommunicationMonitor.StatusChange += (o, a) =>
{
Debug.Console(2, this, "Communication monitor status change: {0}", a.Status);
};
}
public override bool CustomActivate()
{
CommunicationMonitor.Start();
return true;
}
/// <summary>
/// Deactivate method
/// </summary>
public override bool Deactivate()
{
CommunicationMonitor.Stop();

View File

@@ -13,9 +13,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
/// <param name="attachDev"></param>
/// <returns>Attached VideoStatusOutputs or the default if none attached</returns>
/// <summary>
/// GetVideoStatuses method
/// </summary>
public static VideoStatusOutputs GetVideoStatuses(this IAttachVideoStatus attachedDev)
{
// See if this device is connected to a status-providing port
@@ -32,9 +29,6 @@ namespace PepperDash.Essentials.Core
return VideoStatusOutputs.NoStatus;
}
/// <summary>
/// HasVideoStatuses method
/// </summary>
public static bool HasVideoStatuses(this IAttachVideoStatus attachedDev)
{
return TieLineCollection.Default.FirstOrDefault(t =>

View File

@@ -0,0 +1,65 @@
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
List<Feedback> Feedbacks { get; }
}
public static class IHasFeedbackExtensions
{
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
{
CType t = source.GetType();
// get the properties and set them into a new collection of NameType wrappers
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
if (feedbacks != null)
{
Debug.Console(0, source, "\n\nAvailable feedbacks:");
foreach (var f in feedbacks)
{
string val = "";
string type = "";
if (getCurrentStates)
{
if (f is BoolFeedback)
{
val = f.BoolValue.ToString();
type = "boolean";
}
else if (f is IntFeedback)
{
val = f.IntValue.ToString();
type = "integer";
}
else if (f is StringFeedback)
{
val = f.StringValue;
type = "string";
}
}
Debug.Console(0, "{0,-12} {1, -25} {2}", type,
(string.IsNullOrEmpty(f.Cue.Name) ? "-no name-" : f.Cue.Name), val);
}
}
else
Debug.Console(0, source, "No available outputs:");
}
}
}

View File

@@ -0,0 +1,135 @@
<<<<<<< HEAD
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
List<Feedback> Feedbacks { get; }
}
public static class IHasFeedbackExtensions
{
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
{
CType t = source.GetType();
// get the properties and set them into a new collection of NameType wrappers
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
if (feedbacks != null)
{
Debug.Console(0, source, "\n\nAvailable feedbacks:");
foreach (var f in feedbacks)
{
string val = "";
string type = "";
if (getCurrentStates)
{
if (f is BoolFeedback)
{
val = f.BoolValue.ToString();
type = "boolean";
}
else if (f is IntFeedback)
{
val = f.IntValue.ToString();
type = "integer";
}
else if (f is StringFeedback)
{
val = f.StringValue;
type = "string";
}
}
Debug.Console(0, "{0,-12} {1, -25} {2}", type,
(string.IsNullOrEmpty(f.Cue.Name) ? "-no name-" : f.Cue.Name), val);
}
}
else
Debug.Console(0, source, "No available outputs:");
}
}
=======
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
List<Feedback> Feedbacks { get; }
}
public static class IHasFeedbackExtensions
{
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
{
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
if (feedbacks != null)
{
Debug.Console(0, source, "\n\nAvailable feedbacks:");
foreach (var f in feedbacks)
{
string val = "";
if (getCurrentStates)
{
if (f is BoolFeedback)
val = " = " + f.BoolValue;
else if(f is IntFeedback)
val = " = " + f.IntValue;
else if(f is StringFeedback)
val = " = " + f.StringValue;
//switch (f.Type)
//{
// case eCueType.Bool:
// val = " = " + f.BoolValue;
// break;
// case eCueType.Int:
// val = " = " + f.IntValue;
// break;
// case eCueType.String:
// val = " = " + f.StringValue;
// break;
// //case eOutputType.Other:
// // break;
//}
}
Debug.Console(0, "{0,-8} {1}{2}", f.GetType(),
(string.IsNullOrEmpty(f.Cue.Name) ? "-none-" : f.Cue.Name), val);
}
}
else
Debug.Console(0, source, "No available outputs:");
}
}
public static class IHasFeedbackFusionExtensions
{
}
>>>>>>> origin/feature/ecs-307
}

View File

@@ -0,0 +1,63 @@
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
List<Feedback> Feedbacks { get; }
}
public static class IHasFeedbackExtensions
{
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
{
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
if (feedbacks != null)
{
Debug.Console(0, source, "\n\nAvailable feedbacks:");
foreach (var f in feedbacks)
{
string val = "";
if (getCurrentStates)
{
if (f is BoolFeedback)
val = " = " + f.BoolValue;
else if(f is IntFeedback)
val = " = " + f.IntValue;
else if(f is StringFeedback)
val = " = " + f.StringValue;
//switch (f.Type)
//{
// case eCueType.Bool:
// val = " = " + f.BoolValue;
// break;
// case eCueType.Int:
// val = " = " + f.IntValue;
// break;
// case eCueType.String:
// val = " = " + f.StringValue;
// break;
// //case eOutputType.Other:
// // break;
//}
}
Debug.Console(0, "{0,-8} {1}{2}", f.GetType(),
(string.IsNullOrEmpty(f.Cue.Name) ? "-none-" : f.Cue.Name), val);
}
}
else
Debug.Console(0, source, "No available outputs:");
}
}
}

View File

@@ -0,0 +1,65 @@
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
List<Feedback> Feedbacks { get; }
}
public static class IHasFeedbackExtensions
{
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
{
CType t = source.GetType();
// get the properties and set them into a new collection of NameType wrappers
var props = t.GetProperties().Select(p => new PropertyNameType(p, t));
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
if (feedbacks != null)
{
Debug.Console(0, source, "\n\nAvailable feedbacks:");
foreach (var f in feedbacks)
{
string val = "";
string type = "";
if (getCurrentStates)
{
if (f is BoolFeedback)
{
val = f.BoolValue.ToString();
type = "boolean";
}
else if (f is IntFeedback)
{
val = f.IntValue.ToString();
type = "integer";
}
else if (f is StringFeedback)
{
val = f.StringValue;
type = "string";
}
}
Debug.Console(0, "{0,-12} {1, -25} {2}", type,
(string.IsNullOrEmpty(f.Cue.Name) ? "-no name-" : f.Cue.Name), val);
}
}
else
Debug.Console(0, source, "No available outputs:");
}
}
}

View File

@@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IHasFeedback : IKeyed
{
/// <summary>
/// This method shall return a list of all Output objects on a device,
/// including all "aggregate" devices.
/// </summary>
List<Feedback> Feedbacks { get; }
}
public static class IHasFeedbackExtensions
{
public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
{
var feedbacks = source.Feedbacks.OrderBy(x => x.Type);
if (feedbacks != null)
{
Debug.Console(0, source, "\n\nAvailable feedbacks:");
foreach (var f in feedbacks)
{
string val = "";
if (getCurrentStates)
{
if (f is BoolFeedback)
val = " = " + f.BoolValue;
else if(f is IntFeedback)
val = " = " + f.IntValue;
else if(f is StringFeedback)
val = " = " + f.StringValue;
//switch (f.Type)
//{
// case eCueType.Bool:
// val = " = " + f.BoolValue;
// break;
// case eCueType.Int:
// val = " = " + f.IntValue;
// break;
// case eCueType.String:
// val = " = " + f.StringValue;
// break;
// //case eOutputType.Other:
// // break;
//}
}
Debug.Console(0, "{0,-8} {1}{2}", f.GetType(),
(string.IsNullOrEmpty(f.Cue.Name) ? "-none-" : f.Cue.Name), val);
}
}
else
Debug.Console(0, source, "No available outputs:");
}
}
public static class IHasFeedbackFusionExtensions
{
}
}

View File

@@ -1,138 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for IUsageTracking
/// </summary>
public interface IUsageTracking
{
UsageTracking UsageTracker { get; set; }
}
//public static class IUsageTrackingExtensions
//{
// public static void EnableUsageTracker(this IUsageTracking device)
// {
// device.UsageTracker = new UsageTracking();
// }
//}
/// <summary>
/// Represents a UsageTracking
/// </summary>
public class UsageTracking
{
public event EventHandler<DeviceUsageEventArgs> DeviceUsageEnded;
/// <summary>
/// Gets or sets the InUseTracker
/// </summary>
public InUseTracking InUseTracker { get; protected set; }
/// <summary>
/// Gets or sets the UsageIsTracked
/// </summary>
public bool UsageIsTracked { get; set; }
/// <summary>
/// Gets or sets the UsageTrackingStarted
/// </summary>
public bool UsageTrackingStarted { get; protected set; }
/// <summary>
/// Gets or sets the UsageStartTime
/// </summary>
public DateTime UsageStartTime { get; protected set; }
/// <summary>
/// Gets or sets the UsageEndTime
/// </summary>
public DateTime UsageEndTime { get; protected set; }
/// <summary>
/// Gets or sets the Parent
/// </summary>
public Device Parent { get; private set; }
public UsageTracking(Device parent)
{
Parent = parent;
InUseTracker = new InUseTracking();
InUseTracker.InUseFeedback.OutputChange += InUseFeedback_OutputChange; //new EventHandler<EventArgs>();
}
void InUseFeedback_OutputChange(object sender, EventArgs e)
{
if(InUseTracker.InUseFeedback.BoolValue)
{
StartDeviceUsage();
}
else
{
EndDeviceUsage();
}
}
/// <summary>
/// StartDeviceUsage method
/// </summary>
public void StartDeviceUsage()
{
UsageTrackingStarted = true;
UsageStartTime = DateTime.Now;
}
/// <summary>
/// Calculates the difference between the usage start and end times, gets the total minutes used and fires an event to pass that info to a consumer
/// </summary>
public void EndDeviceUsage()
{
try
{
UsageTrackingStarted = false;
UsageEndTime = DateTime.Now;
if (UsageStartTime != null)
{
var timeUsed = UsageEndTime - UsageStartTime;
var handler = DeviceUsageEnded;
if (handler != null)
{
Debug.LogMessage(LogEventLevel.Debug, "Device Usage Ended for: {0} at {1}. In use for {2} minutes.", Parent.Name, UsageEndTime, timeUsed.Minutes);
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
}
}
}
catch (Exception e)
{
Debug.LogMessage(LogEventLevel.Debug, "Error ending device usage: {0}", e);
}
}
}
/// <summary>
/// Represents a DeviceUsageEventArgs
/// </summary>
public class DeviceUsageEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the UsageEndTime
/// </summary>
public DateTime UsageEndTime { get; set; }
/// <summary>
/// Gets or sets the MinutesUsed
/// </summary>
public int MinutesUsed { get; set; }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IUsageTracking
{
UsageTracking UsageTracker { get; set; }
}
//public static class IUsageTrackingExtensions
//{
// public static void EnableUsageTracker(this IUsageTracking device)
// {
// device.UsageTracker = new UsageTracking();
// }
//}
public class UsageTracking
{
public event EventHandler<DeviceUsageEventArgs> DeviceUsageEnded;
public InUseTracking InUseTracker { get; protected set; }
public bool UsageIsTracked { get; set; }
public bool UsageTrackingStarted { get; protected set; }
public DateTime UsageStartTime { get; protected set; }
public DateTime UsageEndTime { get; protected set; }
public Device Parent { get; private set; }
public UsageTracking(Device parent)
{
Parent = parent;
InUseTracker = new InUseTracking();
InUseTracker.InUseFeedback.OutputChange +=new EventHandler<EventArgs>(InUseFeedback_OutputChange);
}
void InUseFeedback_OutputChange(object sender, EventArgs e)
{
if(InUseTracker.InUseFeedback.BoolValue)
{
StartDeviceUsage();
}
else
{
EndDeviceUsage();
}
}
/// <summary>
/// Stores the usage start time
/// </summary>
public void StartDeviceUsage()
{
UsageTrackingStarted = true;
UsageStartTime = DateTime.Now;
}
/// <summary>
/// Calculates the difference between the usage start and end times, gets the total minutes used and fires an event to pass that info to a consumer
/// </summary>
public void EndDeviceUsage()
{
try
{
UsageTrackingStarted = false;
UsageEndTime = DateTime.Now;
if (UsageStartTime != null)
{
var timeUsed = UsageEndTime - UsageStartTime;
var handler = DeviceUsageEnded;
if (handler != null)
{
Debug.Console(1, "Device Usage Ended for: {0} at {1}. In use for {2} minutes.", Parent.Name, UsageEndTime, timeUsed.Minutes);
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
}
}
}
catch (Exception e)
{
Debug.Console(1, "Error ending device usage: {0}", e);
}
}
}
public class DeviceUsageEventArgs : EventArgs
{
public DateTime UsageEndTime { get; set; }
public int MinutesUsed { get; set; }
}
}

View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public interface IUsageTracking
{
UsageTracking UsageTracker { get; set; }
}
//public static class IUsageTrackingExtensions
//{
// public static void EnableUsageTracker(this IUsageTracking device)
// {
// device.UsageTracker = new UsageTracking();
// }
//}
public class UsageTracking
{
public event EventHandler<DeviceUsageEventArgs> DeviceUsageEnded;
public InUseTracking InUseTracker { get; protected set; }
public bool UsageIsTracked { get; set; }
public DateTime UsageStartTime { get; protected set; }
public DateTime UsageEndTime { get; protected set; }
public Device Parent { get; private set; }
public UsageTracking(Device parent)
{
Parent = parent;
InUseTracker = new InUseTracking();
InUseTracker.InUseFeedback.OutputChange +=new EventHandler<EventArgs>(InUseFeedback_OutputChange);
}
void InUseFeedback_OutputChange(object sender, EventArgs e)
{
if(InUseTracker.InUseFeedback.BoolValue)
{
StartDeviceUsage();
}
else
{
EndDeviceUsage();
}
}
/// <summary>
/// Stores the usage start time
/// </summary>
public void StartDeviceUsage()
{
UsageStartTime = DateTime.Now;
}
/// <summary>
/// Calculates the difference between the usage start and end times, gets the total minutes used and fires an event to pass that info to a consumer
/// </summary>
public void EndDeviceUsage()
{
try
{
UsageEndTime = DateTime.Now;
if (UsageStartTime != null)
{
var timeUsed = UsageEndTime - UsageStartTime;
var handler = DeviceUsageEnded;
if (handler != null)
{
Debug.Console(1, "Device Usage Ended for: {0} at {1}. In use for {2} minutes.", Parent.Name, UsageEndTime, timeUsed.Minutes);
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
}
}
}
catch (Exception e)
{
<<<<<<< HEAD
Debug.Console(1, "Device Usage Ended at {0}. In use for {1} minutes.", UsageEndTime, timeUsed.Minutes);
handler(this, new DeviceUsageEventArgs() { UsageEndTime = UsageEndTime, MinutesUsed = timeUsed.Minutes });
=======
Debug.Console(1, "Error ending device usage: {0}", e);
>>>>>>> origin/feature/fusion-nyu
}
}
}
public class DeviceUsageEventArgs : EventArgs
{
public DateTime UsageEndTime { get; set; }
public int MinutesUsed { get; set; }
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines minimal volume control methods
/// </summary>
public interface IBasicVolumeControls
{
void VolumeUp(bool pressRelease);
void VolumeDown(bool pressRelease);
void MuteToggle();
}
/// <summary>
/// Adds feedback and direct volume level set to IBasicVolumeControls
/// </summary>
public interface IBasicVolumeWithFeedback : IBasicVolumeControls
{
void SetVolume(ushort level);
void MuteOn();
void MuteOff();
IntFeedback VolumeLevelFeedback { get; }
BoolFeedback MuteFeedback { get; }
}
/// <summary>
///
/// </summary>
public interface IFullAudioSettings : IBasicVolumeWithFeedback
{
void SetBalance(ushort level);
void BalanceLeft(bool pressRelease);
void BalanceRight(bool pressRelease);
void SetBass(ushort level);
void BassUp(bool pressRelease);
void BassDown(bool pressRelease);
void SetTreble(ushort level);
void TrebleUp(bool pressRelease);
void TrebleDown(bool pressRelease);
bool hasMaxVolume { get; }
void SetMaxVolume(ushort level);
void MaxVolumeUp(bool pressRelease);
void MaxVolumeDown(bool pressRelease);
bool hasDefaultVolume { get; }
void SetDefaultVolume(ushort level);
void DefaultVolumeUp(bool pressRelease);
void DefaultVolumeDown(bool pressRelease);
void LoudnessToggle();
void MonoToggle();
BoolFeedback LoudnessFeedback { get; }
BoolFeedback MonoFeedback { get; }
IntFeedback BalanceFeedback { get; }
IntFeedback BassFeedback { get; }
IntFeedback TrebleFeedback { get; }
IntFeedback MaxVolumeFeedback { get; }
IntFeedback DefaultVolumeFeedback { get; }
}
/// <summary>
/// A class that implements this, contains a reference to an IBasicVolumeControls device.
/// For example, speakers attached to an audio zone. The speakers can provide reference
/// to their linked volume control.
/// </summary>
public interface IHasVolumeDevice
{
IBasicVolumeControls VolumeDevice { get; }
}
/// <summary>
/// Identifies a device that contains audio zones
/// </summary>
public interface IAudioZones : IRouting
{
Dictionary<uint, IAudioZone> Zone { get; }
}
/// <summary>
/// Defines minimum functionality for an audio zone
/// </summary>
public interface IAudioZone : IBasicVolumeWithFeedback
{
void SelectInput(ushort input);
}
}

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// IR port wrapper. May act standalone
/// </summary>
public class IrOutputPortController : Device
{
uint IrPortUid;
IROutputPort IrPort;
public ushort StandardIrPulseTime { get; set; }
public string DriverFilepath { get; private set; }
public bool DriverIsLoaded { get; private set; }
/// <summary>
/// Constructor for IrDevice base class. If a null port is provided, this class will
/// still function without trying to talk to a port.
/// </summary>
public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath)
: base(key)
{
//if (port == null) throw new ArgumentNullException("port");
IrPort = port;
if (port == null)
{
Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function");
return;
}
LoadDriver(irDriverFilepath);
}
/// <summary>
/// Loads the IR driver at path
/// </summary>
/// <param name="path"></param>
public void LoadDriver(string path)
{
if (string.IsNullOrEmpty(path)) path = DriverFilepath;
try
{
IrPortUid = IrPort.LoadIRDriver(path);
DriverFilepath = path;
StandardIrPulseTime = 200;
DriverIsLoaded = true;
}
catch
{
DriverIsLoaded = false;
var message = string.Format("WARNING IR Driver '{0}' failed to load", path);
Debug.Console(0, this, message);
ErrorLog.Error(message);
}
}
/// <summary>
/// Starts and stops IR command on driver. Safe for missing commands
/// </summary>
public virtual void PressRelease(string command, bool state)
{
Debug.Console(2, this, "IR:'{0}'={1}", command, state);
if (IrPort == null)
{
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
return;
}
if (!DriverIsLoaded)
{
Debug.Console(2, this, "WARNING IR driver is not loaded");
return;
}
if (state)
{
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
IrPort.Press(IrPortUid, command);
else
NoIrCommandError(command);
}
else
IrPort.Release();
}
/// <summary>
/// Pulses a command on driver. Safe for missing commands
/// </summary>
public virtual void Pulse(string command, ushort time)
{
if (IrPort == null)
{
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
return;
}
if (!DriverIsLoaded)
{
Debug.Console(2, this, "WARNING IR driver is not loaded");
return;
}
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
IrPort.PressAndRelease(IrPortUid, command, time);
else
NoIrCommandError(command);
}
/// <summary>
/// Notifies the console when a bad command is used.
/// </summary>
protected void NoIrCommandError(string command)
{
Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}",
Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command);
}
///// <summary>
///// When fed a dictionary of uint, string, will return UOs for each item,
///// attached to this IrOutputPort
///// </summary>
///// <param name="numStringDict"></param>
///// <returns></returns>
//public List<CueActionPair> GetUOsForIrCommands(Dictionary<Cue, string> numStringDict)
//{
// var funcs = new List<CueActionPair>(numStringDict.Count);
// foreach (var kvp in numStringDict)
// {
// // Have to assign these locally because of kvp's scope
// var cue = kvp.Key;
// var command = kvp.Value;
// funcs.Add(new BoolCueActionPair(cue, b => this.PressRelease(command, b)));
// }
// return funcs;
//}
}
}

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials.Core
{
//public interface IVolumeFunctions
//{
// BoolCueActionPair VolumeUpCueActionPair { get; }
// BoolCueActionPair VolumeDownCueActionPair { get; }
// BoolCueActionPair MuteToggleCueActionPair { get; }
//}
//public interface IVolumeTwoWay : IVolumeFunctions
//{
// IntFeedback VolumeLevelFeedback { get; }
// UShortCueActionPair VolumeLevelCueActionPair { get; }
// BoolFeedback IsMutedFeedback { get; }
//}
///// <summary>
/////
///// </summary>
//public static class IFunctionListExtensions
//{
// public static string GetFunctionsConsoleList(this IHasCueActionList device)
// {
// var sb = new StringBuilder();
// var list = device.CueActionList;
// foreach (var cap in list)
// sb.AppendFormat("{0,-15} {1,4} {2}\r", cap.Cue.Name, cap.Cue.Number, cap.GetType().Name);
// return sb.ToString();
// }
//}
public enum AudioChangeType
{
Mute, Volume
}
public class AudioChangeEventArgs
{
public AudioChangeType ChangeType { get; private set; }
public IBasicVolumeControls AudioDevice { get; private set; }
public AudioChangeEventArgs(IBasicVolumeControls device, AudioChangeType changeType)
{
ChangeType = changeType;
AudioDevice = device;
}
}
}

View File

@@ -9,9 +9,18 @@ using Crestron.SimplSharpPro.UI;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Enumeration of PresentationSourceType values
/// </summary>
//[Obsolete]
//public class PresentationDeviceType
//{
// public const ushort Default = 1;
// public const ushort CableSetTopBox = 2;
// public const ushort SatelliteSetTopBox = 3;
// public const ushort Dvd = 4;
// public const ushort Bluray = 5;
// public const ushort PC = 9;
// public const ushort Laptop = 10;
//}
public enum PresentationSourceType
{
None, Dvd, Laptop, PC, SetTopBox, VCR

View File

@@ -0,0 +1,56 @@
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
//public interface IHasFeedback : IKeyed
//{
// /// <summary>
// /// This method shall return a list of all Output objects on a device,
// /// including all "aggregate" devices.
// /// </summary>
// List<Feedback> Feedbacks { get; }
//}
//public static class IHasFeedbackExtensions
//{
// public static void DumpFeedbacksToConsole(this IHasFeedback source, bool getCurrentStates)
// {
// var outputs = source.Feedbacks.OrderBy(x => x.Type);
// if (outputs != null)
// {
// Debug.Console(0, source, "\n\nAvailable outputs:");
// foreach (var o in outputs)
// {
// string val = "";
// if (getCurrentStates)
// {
// switch (o.Type)
// {
// case eCueType.Bool:
// val = " = " + o.BoolValue;
// break;
// case eCueType.Int:
// val = " = " + o.IntValue;
// break;
// case eCueType.String:
// val = " = " + o.StringValue;
// break;
// //case eOutputType.Other:
// // break;
// }
// }
// Debug.Console(0, "{0,-8} {1,5} {2}{3}", o.Type, o.Cue.Number,
// (string.IsNullOrEmpty(o.Cue.Name) ? "-none-" : o.Cue.Name), val);
// }
// }
// else
// Debug.Console(0, source, "No available outputs:");
// }
//}
}

View File

@@ -1,9 +1,6 @@

namespace PepperDash.Essentials.Core
{
/// <summary>
/// Represents a SmartObjectJoinOffsets
/// </summary>
public class SmartObjectJoinOffsets
{
public const ushort Dpad = 1;

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public enum eSourceListItemType
{
Route, Off, Other, SomethingAwesomerThanThese
}
/// <summary>
/// Represents an item in a source list - can be deserialized into.
/// </summary>
public class SourceListItem
{
public string SourceKey { get; set; }
/// <summary>
/// Returns the source Device for this, if it exists in DeviceManager
/// </summary>
[JsonIgnore]
public Device SourceDevice
{
get
{
if (_SourceDevice == null)
_SourceDevice = DeviceManager.GetDeviceForKey(SourceKey) as Device;
return _SourceDevice;
}
}
Device _SourceDevice;
/// <summary>
/// Gets either the source's Name or this AlternateName property, if
/// defined. If source doesn't exist, returns "Missing source"
/// </summary>
public string PreferredName
{
get
{
if (string.IsNullOrEmpty(Name))
{
if (SourceDevice == null)
return "---";
return SourceDevice.Name;
}
return Name;
}
}
/// <summary>
/// A name that will override the source's name on the UI
/// </summary>
public string Name { get; set; }
public string Icon { get; set; }
public string AltIcon { get; set; }
public bool IncludeInSourceList { get; set; }
public int Order { get; set; }
public string VolumeControlKey { get; set; }
public eSourceListItemType Type { get; set; }
public List<SourceRouteListItem> RouteList { get; set; }
public SourceListItem()
{
Icon = "Blank";
}
}
public class SourceRouteListItem
{
[JsonProperty("sourceKey")]
public string SourceKey { get; set; }
[JsonProperty("destinationKey")]
public string DestinationKey { get; set; }
[JsonProperty("type")]
public eRoutingSignalType Type { get; set; }
}
}

View File

@@ -1,47 +1,30 @@
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;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using Serilog.Events;
using PepperDash.Essentials.Core.Routing;
namespace PepperDash.Essentials.Devices.Common.Displays
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Represents a BasicIrDisplay
/// </summary>
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IPower, IWarmingCooling, IRoutingSinkWithSwitching
{
/// <summary>
/// Gets or sets the IrPort
/// </summary>
public IrOutputPortController IrPort { get; private set; }
/// <summary>
/// Gets or sets the IrPulseTime
/// </summary>
public ushort IrPulseTime { get; set; }
/// <summary>
/// Gets the power is on feedback function
/// </summary>
protected Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
protected override Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
}
/// <summary>
/// Gets the is cooling down feedback function
/// </summary>
protected override Func<bool> IsCoolingDownFeedbackFunc
{
get { return () => _IsCoolingDown; }
}
/// <summary>
/// Gets the is warming up feedback function
/// </summary>
protected override Func<bool> IsWarmingUpFeedbackFunc
{
get { return () => _IsWarmingUp; }
@@ -51,92 +34,69 @@ namespace PepperDash.Essentials.Devices.Common.Displays
bool _IsWarmingUp;
bool _IsCoolingDown;
/// <summary>
/// Initializes a new instance of the BasicIrDisplay class
/// </summary>
/// <param name="key">The device key</param>
/// <param name="name">The device name</param>
/// <param name="port">The IR output port</param>
/// <param name="irDriverFilepath">The path to the IR driver file</param>
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
: base(key, name)
{
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
DeviceManager.AddDevice(IrPort);
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Verbose, this, "Warming up={0}", _IsWarmingUp);
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.LogMessage(LogEventLevel.Verbose, this, "Cooling down={0}", _IsCoolingDown);
PowerIsOnFeedback.OutputChange += (o, a) => {
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
if (_PowerIsOn) StartWarmingTimer();
else StartCoolingTimer();
};
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
{
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
});
}
/// <summary>
/// Hdmi1 method
/// </summary>
public void Hdmi1()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
}
/// <summary>
/// Hdmi2 method
/// </summary>
public void Hdmi2()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
}
/// <summary>
/// Hdmi3 method
/// </summary>
public void Hdmi3()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
}
/// <summary>
/// Hdmi4 method
/// </summary>
public void Hdmi4()
{
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
}
/// <summary>
/// Component1 method
/// </summary>
public void Component1()
{
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
}
/// <summary>
/// Video1 method
/// </summary>
public void Video1()
{
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
}
/// <summary>
/// Antenna method
/// </summary>
public void Antenna()
{
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
@@ -144,31 +104,24 @@ namespace PepperDash.Essentials.Devices.Common.Displays
#region IPower Members
/// <summary>
/// PowerOn method
/// </summary>
/// <inheritdoc />
public override void PowerOn()
{
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
_PowerIsOn = true;
PowerIsOnFeedback.FireUpdate();
}
/// <summary>
/// PowerOff method
/// </summary>
public override void PowerOff()
{
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
}
/// <summary>
/// PowerToggle method
/// </summary>
public override void PowerToggle()
{
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
}
@@ -176,25 +129,16 @@ namespace PepperDash.Essentials.Devices.Common.Displays
#region IBasicVolumeControls Members
/// <summary>
/// VolumeUp method
/// </summary>
public void VolumeUp(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
}
/// <summary>
/// VolumeDown method
/// </summary>
public void VolumeDown(bool pressRelease)
{
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
}
/// <summary>
/// MuteToggle method
/// </summary>
public void MuteToggle()
{
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
@@ -206,8 +150,7 @@ namespace PepperDash.Essentials.Devices.Common.Displays
{
_IsWarmingUp = true;
IsWarmingUpFeedback.FireUpdate();
new CTimer(o =>
{
new CTimer(o => {
_IsWarmingUp = false;
IsWarmingUpFeedback.FireUpdate();
}, 10000);
@@ -230,13 +173,8 @@ namespace PepperDash.Essentials.Devices.Common.Displays
/// Typically called by the discovery routing algorithm.
/// </summary>
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
/// <summary>
/// ExecuteSwitch method
/// </summary>
/// <inheritdoc />
public override void ExecuteSwitch(object inputSelector)
{
Debug.LogMessage(LogEventLevel.Verbose, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
Action finishSwitch = () =>
{
@@ -245,10 +183,10 @@ namespace PepperDash.Essentials.Devices.Common.Displays
action();
};
if (!_PowerIsOn)
if (!PowerIsOnFeedback.BoolValue)
{
PowerOn();
EventHandler<FeedbackEventArgs> oneTimer = null;
EventHandler<EventArgs> oneTimer = null;
oneTimer = (o, a) =>
{
if (IsWarmingUpFeedback.BoolValue) return; // Only catch done warming
@@ -262,46 +200,5 @@ namespace PepperDash.Essentials.Devices.Common.Displays
}
#endregion
/// <summary>
/// LinkToApi method
/// </summary>
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
}
}
/// <summary>
/// Represents a BasicIrDisplayFactory
/// </summary>
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
{
/// <summary>
/// Initializes a new instance of the BasicIrDisplayFactory class
/// </summary>
public BasicIrDisplayFactory()
{
TypeNames = new List<string>() { "basicirdisplay" };
}
/// <summary>
/// BuildDevice method
/// </summary>
/// <inheritdoc />
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.LogMessage(LogEventLevel.Debug, "Factory Attempting to create new BasicIrDisplay Device");
var ir = IRPortHelper.GetIrPort(dc.Properties);
if (ir != null)
{
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
display.IrPulseTime = 200; // Set default pulse time for IR commands.
return display;
}
return null;
}
}
}

View File

@@ -0,0 +1,105 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro;
//namespace PepperDash.Essentials.Core
//{
// public abstract class IRDisplayBase : DisplayBase, IHasCueActionList
// {
// public IrOutputPortController IrPort { get; private set; }
// /// <summary>
// /// Default to 200ms
// /// </summary>
// public ushort IrPulseTime { get; set; }
// bool _PowerIsOn;
// bool _IsWarmingUp;
// bool _IsCoolingDown;
// /// <summary>
// /// FunctionList is pre-defined to have power commands.
// /// </summary>
// public IRDisplayBase(string key, string name, IROutputPort port, string irDriverFilepath)
// : base(key, name)
// {
// IrPort = new IrOutputPortController("ir-" + key, port, irDriverFilepath);
// IrPulseTime = 200;
// WarmupTime = 7000;
// CooldownTime = 10000;
// CueActionList = new List<CueActionPair>
// {
// new BoolCueActionPair(CommonBoolCue.Power, b=> PowerToggle()),
// new BoolCueActionPair(CommonBoolCue.PowerOn, b=> PowerOn()),
// new BoolCueActionPair(CommonBoolCue.PowerOff, b=> PowerOff()),
// };
// }
// public override void PowerOn()
// {
// if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
// {
// _IsWarmingUp = true;
// IsWarmingUpFeedback.FireUpdate();
// // Fake power-up cycle
// WarmupTimer = new CTimer(o =>
// {
// _IsWarmingUp = false;
// _PowerIsOn = true;
// IsWarmingUpFeedback.FireUpdate();
// PowerIsOnFeedback.FireUpdate();
// }, WarmupTime);
// }
// IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
// }
// public override void PowerOff()
// {
// // If a display has unreliable-power off feedback, just override this and
// // remove this check.
// if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
// {
// _IsCoolingDown = true;
// _PowerIsOn = false;
// PowerIsOnFeedback.FireUpdate();
// IsCoolingDownFeedback.FireUpdate();
// // Fake cool-down cycle
// CooldownTimer = new CTimer(o =>
// {
// _IsCoolingDown = false;
// IsCoolingDownFeedback.FireUpdate();
// }, CooldownTime);
// }
// IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
// }
// public override void PowerToggle()
// {
// // Not sure how to handle the feedback, but we should default to power off fb.
// // Does this need to trigger feedback??
// _PowerIsOn = false;
// IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
// }
// #region IFunctionList Members
// public List<CueActionPair> CueActionList
// {
// get;
// private set;
// }
// #endregion
// protected override Func<bool> PowerIsOnOutputFunc { get { return () => _PowerIsOn; } }
// protected override Func<bool> IsCoolingDownOutputFunc { get { return () => _IsCoolingDown; } }
// protected override Func<bool> IsWarmingUpOutputFunc { get { return () => _IsWarmingUp; } }
// public override void ExecuteSwitch(object selector)
// {
// IrPort.Pulse((string)selector, IrPulseTime);
// }
// }
//}

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public abstract class DisplayBase : Device, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking
{
public BoolFeedback PowerIsOnFeedback { get; protected set; }
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
public BoolFeedback IsWarmingUpFeedback { get; private set; }
public UsageTracking UsageTracker { get; set; }
public uint WarmupTime { get; set; }
public uint CooldownTime { get; set; }
/// <summary>
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
/// by concrete sub-classes
/// </summary>
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
protected CTimer WarmupTimer;
protected CTimer CooldownTimer;
#region IRoutingInputs Members
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
#endregion
public DisplayBase(string key, string name)
: base(key, name)
{
PowerIsOnFeedback = new BoolFeedback(CommonBoolCue.PowerOnFeedback, PowerIsOnFeedbackFunc);
IsCoolingDownFeedback = new BoolFeedback(CommonBoolCue.IsCoolingDown, IsCoolingDownFeedbackFunc);
IsWarmingUpFeedback = new BoolFeedback(CommonBoolCue.IsWarmingUp, IsWarmingUpFeedbackFunc);
InputPorts = new RoutingPortCollection<RoutingInputPort>();
PowerIsOnFeedback.OutputChange += new EventHandler<EventArgs>(PowerIsOnFeedback_OutputChange);
}
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
{
if (UsageTracker != null)
{
if (PowerIsOnFeedback.BoolValue)
UsageTracker.StartDeviceUsage();
else
UsageTracker.EndDeviceUsage();
}
}
public abstract void PowerOn();
public abstract void PowerOff();
public abstract void PowerToggle();
public virtual List<Feedback> Feedbacks
{
get
{
return new List<Feedback>
{
PowerIsOnFeedback,
IsCoolingDownFeedback,
IsWarmingUpFeedback
};
}
}
public abstract void ExecuteSwitch(object selector);
}
/// <summary>
///
/// </summary>
public abstract class TwoWayDisplayBase : DisplayBase
{
public StringFeedback CurrentInputFeedback { get; private set; }
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
public static MockDisplay DefaultDisplay
{
get
{
if (_DefaultDisplay == null)
_DefaultDisplay = new MockDisplay("default", "Default Display");
return _DefaultDisplay;
}
}
static MockDisplay _DefaultDisplay;
public TwoWayDisplayBase(string key, string name)
: base(key, name)
{
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
WarmupTime = 7000;
CooldownTime = 15000;
Feedbacks.Add(CurrentInputFeedback);
}
}
}

View File

@@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
using PepperDash.Essentials.Core.Routing;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public class MockDisplay : TwoWayDisplayBase, IBasicVolumeWithFeedback
{
public RoutingInputPort HdmiIn1 { get; private set; }
public RoutingInputPort HdmiIn2 { get; private set; }
public RoutingInputPort HdmiIn3 { get; private set; }
public RoutingInputPort ComponentIn1 { get; private set; }
public RoutingInputPort VgaIn1 { get; private set; }
bool _PowerIsOn;
bool _IsWarmingUp;
bool _IsCoolingDown;
protected override Func<bool> PowerIsOnFeedbackFunc { get { return () => _PowerIsOn; } }
protected override Func<bool> IsCoolingDownFeedbackFunc { get { return () => _IsCoolingDown; } }
protected override Func<bool> IsWarmingUpFeedbackFunc { get { return () => _IsWarmingUp; } }
protected override Func<string> CurrentInputFeedbackFunc { get { return () => "Not Implemented"; } }
int VolumeHeldRepeatInterval = 200;
ushort VolumeInterval = 655;
ushort _FakeVolumeLevel = 31768;
bool _IsMuted;
public MockDisplay(string key, string name)
: base(key, name)
{
HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, null, this);
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, null, this);
HdmiIn3 = new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, null, this);
ComponentIn1 = new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Video,
eRoutingPortConnectionType.Component, null, this);
VgaIn1 = new RoutingInputPort(RoutingPortNames.VgaIn, eRoutingSignalType.Video,
eRoutingPortConnectionType.Composite, null, this);
InputPorts.AddRange(new[] { HdmiIn1, HdmiIn2, HdmiIn3, ComponentIn1, VgaIn1 });
VolumeLevelFeedback = new IntFeedback(() => { return _FakeVolumeLevel; });
MuteFeedback = new BoolFeedback(CommonBoolCue.MuteOn, () => _IsMuted);
}
public override void PowerOn()
{
if (!PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsWarmingUp = true;
IsWarmingUpFeedback.FireUpdate();
// Fake power-up cycle
WarmupTimer = new CTimer(o =>
{
_IsWarmingUp = false;
_PowerIsOn = true;
IsWarmingUpFeedback.FireUpdate();
PowerIsOnFeedback.FireUpdate();
}, WarmupTime);
}
}
public override void PowerOff()
{
// If a display has unreliable-power off feedback, just override this and
// remove this check.
if (PowerIsOnFeedback.BoolValue && !_IsWarmingUp && !_IsCoolingDown)
{
_IsCoolingDown = true;
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
IsCoolingDownFeedback.FireUpdate();
// Fake cool-down cycle
CooldownTimer = new CTimer(o =>
{
Debug.Console(2, this, "Cooldown timer ending");
_IsCoolingDown = false;
IsCoolingDownFeedback.FireUpdate();
}, CooldownTime);
}
}
public override void PowerToggle()
{
if (PowerIsOnFeedback.BoolValue && !IsWarmingUpFeedback.BoolValue)
PowerOff();
else if (!PowerIsOnFeedback.BoolValue && !IsCoolingDownFeedback.BoolValue)
PowerOn();
}
public override void ExecuteSwitch(object selector)
{
Debug.Console(2, this, "ExecuteSwitch: {0}", selector);
}
#region IBasicVolumeWithFeedback Members
public IntFeedback VolumeLevelFeedback { get; private set; }
public void SetVolume(ushort level)
{
_FakeVolumeLevel = level;
VolumeLevelFeedback.FireUpdate();
}
public void MuteOn()
{
_IsMuted = true;
MuteFeedback.FireUpdate();
}
public void MuteOff()
{
_IsMuted = false;
MuteFeedback.FireUpdate();
}
public BoolFeedback MuteFeedback { get; private set; }
#endregion
#region IBasicVolumeControls Members
public void VolumeUp(bool pressRelease)
{
//while (pressRelease)
//{
Debug.Console(2, this, "Volume Down {0}", pressRelease);
if (pressRelease)
{
var newLevel = _FakeVolumeLevel + VolumeInterval;
SetVolume((ushort)newLevel);
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
}
//}
}
public void VolumeDown(bool pressRelease)
{
//while (pressRelease)
//{
Debug.Console(2, this, "Volume Up {0}", pressRelease);
if (pressRelease)
{
var newLevel = _FakeVolumeLevel - VolumeInterval;
SetVolume((ushort)newLevel);
CrestronEnvironment.Sleep(VolumeHeldRepeatInterval);
}
//}
}
public void MuteToggle()
{
_IsMuted = !_IsMuted;
MuteFeedback.FireUpdate();
}
#endregion
}
}

View File

@@ -10,24 +10,35 @@ namespace PepperDash.Essentials.Core.Ethernet
{
public static class EthernetSettings
{
public static readonly BoolFeedback LinkActive = new BoolFeedback("LinkActive",
public static readonly BoolFeedback LinkActive = new BoolFeedback(EthernetCue.LinkActive,
() => true);
public static readonly BoolFeedback DhcpActive = new BoolFeedback("DhcpActive",
public static readonly BoolFeedback DhcpActive = new BoolFeedback(EthernetCue.DhcpActive,
() => CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, 0) == "ON");
public static readonly StringFeedback Hostname = new StringFeedback("Hostname",
public static readonly StringFeedback Hostname = new StringFeedback(EthernetCue.Hostname,
() => CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0));
public static readonly StringFeedback IpAddress0 = new StringFeedback("IpAddress0",
public static readonly StringFeedback IpAddress0 = new StringFeedback(EthernetCue.IpAddress0,
() => CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
public static readonly StringFeedback SubnetMask0 = new StringFeedback("SubnetMask0",
public static readonly StringFeedback SubnetMask0 = new StringFeedback(EthernetCue.SubnetMask0,
() => CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, 0));
public static readonly StringFeedback DefaultGateway0 = new StringFeedback("DefaultGateway0",
public static readonly StringFeedback DefaultGateway0 = new StringFeedback(EthernetCue.DefaultGateway0,
() => CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, 0));
}
public static class EthernetCue
{
public static readonly Cue LinkActive = Cue.BoolCue("LinkActive", 1);
public static readonly Cue DhcpActive = Cue.BoolCue("DhcpActive", 2);
public static readonly Cue Hostname = Cue.StringCue("Hostname", 1);
public static readonly Cue IpAddress0 = Cue.StringCue("IpAddress0", 2);
public static readonly Cue SubnetMask0 = Cue.StringCue("SubnetMask0", 3);
public static readonly Cue DefaultGateway0 = Cue.StringCue("DefaultGateway0", 4);
}
}

View File

@@ -6,24 +6,15 @@ using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Represents a BoolFeedbackPulse
/// </summary>
public class BoolFeedbackPulse
{
/// <summary>
/// Gets or sets the TimeoutMs
/// </summary>
public uint TimeoutMs { get; set; }
/// <summary>
/// Gets or sets the CanRetrigger
/// </summary>
/// <summary>
/// Defaults to false
/// </summary>
public bool CanRetrigger { get; set; }
/// <summary>
/// Gets or sets the Feedback
/// </summary>
public BoolFeedback Feedback { get; private set; }
CTimer Timer;
@@ -51,9 +42,6 @@ namespace PepperDash.Essentials.Core
/// Starts the
/// </summary>
/// <param name="timeout"></param>
/// <summary>
/// Start method
/// </summary>
public void Start()
{
if (Timer == null)
@@ -72,9 +60,6 @@ namespace PepperDash.Essentials.Core
Timer.Reset(TimeoutMs);
}
/// <summary>
/// Cancel method
/// </summary>
public void Cancel()
{
if(Timer != null)

View File

@@ -11,9 +11,9 @@ namespace PepperDash.Essentials.Core
public abstract class BoolFeedbackLogic
{
/// <summary>
/// Gets or sets the Output
/// </summary>
/// <summary>
/// Output representing the "and" value of all connected inputs
/// </summary>
public BoolFeedback Output { get; private set; }
/// <summary>
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Core
protected bool ComputedValue;
protected BoolFeedbackLogic()
public BoolFeedbackLogic()
{
Output = new BoolFeedback(() => ComputedValue);
}
@@ -38,35 +38,29 @@ namespace PepperDash.Essentials.Core
Evaluate();
}
/// <summary>
/// AddOutputsIn method
/// </summary>
public void AddOutputsIn(List<BoolFeedback> outputs)
{
foreach (var o in outputs.Where(o => !OutputsIn.Contains(o)))
{
OutputsIn.Add(o);
o.OutputChange += AnyInput_OutputChange;
}
Evaluate();
foreach (var o in outputs)
{
// skip existing
if (OutputsIn.Contains(o)) continue;
OutputsIn.Add(o);
o.OutputChange += AnyInput_OutputChange;
}
Evaluate();
}
/// <summary>
/// RemoveOutputIn method
/// </summary>
public void RemoveOutputIn(BoolFeedback output)
public void RemoveOutputIn(BoolFeedback output)
{
// Don't double up outputs
if (!OutputsIn.Contains(output)) return;
if (OutputsIn.Contains(output)) return;
OutputsIn.Remove(output);
output.OutputChange -= AnyInput_OutputChange;
Evaluate();
}
/// <summary>
/// RemoveOutputsIn method
/// </summary>
public void RemoveOutputsIn(List<BoolFeedback> outputs)
{
foreach (var o in outputs)
@@ -77,15 +71,6 @@ namespace PepperDash.Essentials.Core
Evaluate();
}
/// <summary>
/// ClearOutputs method
/// </summary>
public void ClearOutputs()
{
OutputsIn.Clear();
Evaluate();
}
void AnyInput_OutputChange(object sender, EventArgs e)
{
Evaluate();
@@ -94,65 +79,53 @@ namespace PepperDash.Essentials.Core
protected abstract void Evaluate();
}
/// <summary>
/// Represents a BoolFeedbackAnd
/// </summary>
public class BoolFeedbackAnd : BoolFeedbackLogic
{
protected override void Evaluate()
{
var prevValue = ComputedValue;
var newValue = OutputsIn.All(o => o.BoolValue);
if (newValue == prevValue)
{
return;
}
ComputedValue = newValue;
Output.FireUpdate();
if (newValue != prevValue)
{
ComputedValue = newValue;
Output.FireUpdate();
}
}
}
/// <summary>
/// Represents a BoolFeedbackOr
/// </summary>
public class BoolFeedbackOr : BoolFeedbackLogic
{
protected override void Evaluate()
{
var prevValue = ComputedValue;
var newValue = OutputsIn.Any(o => o.BoolValue);
if (newValue == prevValue)
{
return;
}
ComputedValue = newValue;
Output.FireUpdate();
if (newValue != prevValue)
{
ComputedValue = newValue;
Output.FireUpdate();
}
}
}
/// <summary>
/// Represents a BoolFeedbackLinq
/// </summary>
public class BoolFeedbackLinq : BoolFeedbackLogic
{
readonly Func<IEnumerable<BoolFeedback>, bool> _predicate;
Func<IEnumerable<BoolFeedback>, bool> Predicate;
public BoolFeedbackLinq(Func<IEnumerable<BoolFeedback>, bool> predicate)
: base()
{
_predicate = predicate;
Predicate = predicate;
}
protected override void Evaluate()
{
var prevValue = ComputedValue;
var newValue = _predicate(OutputsIn);
if (newValue == prevValue)
{
return;
}
ComputedValue = newValue;
Output.FireUpdate();
var newValue = Predicate(OutputsIn);
if (newValue != prevValue)
{
ComputedValue = newValue;
Output.FireUpdate();
}
}
}
}

View File

@@ -0,0 +1,235 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core
{
public abstract class Feedback
{
public event EventHandler<EventArgs> OutputChange;
public virtual bool BoolValue { get { return false; } }
public virtual int IntValue { get { return 0; } }
public virtual string StringValue { get { return ""; } }
public Cue Cue { get; private set; }
public abstract eCueType Type { get; }
protected Feedback()
{
}
protected Feedback(Cue cue)
{
Cue = cue;
}
public abstract void FireUpdate();
protected void OnOutputChange()
{
if (OutputChange != null) OutputChange(this, EventArgs.Empty);
}
}
/// <summary>
/// A Feedback whose output is derived from the return value of a provided Func.
/// </summary>
public class BoolFeedback : Feedback
{
/// <summary>
/// Returns the current value of the feedback, derived from the ValueFunc
/// </summary>
public override bool BoolValue { get { return _BoolValue; } }
bool _BoolValue;
public override eCueType Type { get { return eCueType.Bool; } }
public Func<bool> ValueFunc { get; private set; }
/// <summary>
/// The last value delivered on FireUpdate
/// </summary>
//public bool PreviousValue { get; private set; }
List<BoolInputSig> LinkedInputSigs = new List<BoolInputSig>();
List<BoolInputSig> LinkedComplementInputSigs = new List<BoolInputSig>();
public BoolFeedback(Func<bool> valueFunc)
: this(Cue.DefaultBoolCue, valueFunc)
{
}
public BoolFeedback(Cue cue, Func<bool> valueFunc)
: base(cue)
{
if (cue == null) throw new ArgumentNullException("cue");
ValueFunc = valueFunc;
}
public override void FireUpdate()
{
var newValue = ValueFunc.Invoke();
if (newValue != _BoolValue)
{
_BoolValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s));
LinkedComplementInputSigs.ForEach(s => UpdateComplementSig(s));
OnOutputChange();
}
}
public void LinkInputSig(BoolInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(BoolInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public void LinkComplementInputSig(BoolInputSig sig)
{
LinkedComplementInputSigs.Add(sig);
UpdateComplementSig(sig);
}
public void UnlinkComplementInputSig(BoolInputSig sig)
{
LinkedComplementInputSigs.Remove(sig);
}
public override string ToString()
{
return BoolValue.ToString();
}
void UpdateSig(BoolInputSig sig)
{
sig.BoolValue = _BoolValue;
}
void UpdateComplementSig(BoolInputSig sig)
{
sig.BoolValue = !_BoolValue;
}
}
//******************************************************************************
public class IntFeedback : Feedback
{
public override int IntValue { get { return _IntValue; } } // ValueFunc.Invoke(); } }
int _IntValue;
public ushort UShortValue { get { return (ushort)_IntValue; } }
public override eCueType Type { get { return eCueType.Int; } }
//public int PreviousValue { get; private set; }
Func<int> ValueFunc;
List<UShortInputSig> LinkedInputSigs = new List<UShortInputSig>();
public IntFeedback(Func<int> valueFunc)
: this(Cue.DefaultIntCue, valueFunc)
{
}
public IntFeedback(Cue cue, Func<int> valueFunc)
: base(cue)
{
if (cue == null) throw new ArgumentNullException("cue");
ValueFunc = valueFunc;
}
public override void FireUpdate()
{
var newValue = ValueFunc.Invoke();
if (newValue != _IntValue)
{
_IntValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s));
OnOutputChange();
}
}
public void LinkInputSig(UShortInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(UShortInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public override string ToString()
{
return IntValue.ToString();
}
void UpdateSig(UShortInputSig sig)
{
sig.UShortValue = UShortValue;
}
}
//******************************************************************************
public class StringFeedback : Feedback
{
public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } }
string _StringValue;
public override eCueType Type { get { return eCueType.String; } }
//public string PreviousValue { get; private set; }
public Func<string> ValueFunc { get; private set; }
List<StringInputSig> LinkedInputSigs = new List<StringInputSig>();
public StringFeedback(Func<string> valueFunc)
: this(Cue.DefaultStringCue, valueFunc)
{
}
public StringFeedback(Cue cue, Func<string> valueFunc)
: base(cue)
{
if (cue == null) throw new ArgumentNullException("cue");
ValueFunc = valueFunc;
}
public override void FireUpdate()
{
var newValue = ValueFunc.Invoke();
if (newValue != _StringValue)
{
_StringValue = newValue;
LinkedInputSigs.ForEach(s => UpdateSig(s));
OnOutputChange();
}
}
public void LinkInputSig(StringInputSig sig)
{
LinkedInputSigs.Add(sig);
UpdateSig(sig);
}
public void UnlinkInputSig(StringInputSig sig)
{
LinkedInputSigs.Remove(sig);
}
public override string ToString()
{
return StringValue;
}
void UpdateSig(StringInputSig sig)
{
sig.StringValue = _StringValue;
}
}
}

View File

@@ -0,0 +1,377 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro;
//using Crestron.SimplSharpPro.DeviceSupport;
//using Crestron.SimplSharpPro.Fusion;
//using PepperDash.Essentials.Core;
//using PepperDash.Core;
//namespace PepperDash.Essentials.Core.Fusion
//{
// public class EssentialsHuddleSpaceFusionSystemController : Device
// {
// FusionRoom FusionRoom;
// Room Room;
// Dictionary<IPresentationSource, BoolInputSig> SourceToFeedbackSigs = new Dictionary<IPresentationSource, BoolInputSig>();
// StatusMonitorCollection ErrorMessageRollUp;
// public EssentialsHuddleSpaceFusionSystemController(HuddleSpaceRoom room, uint ipId)
// : base(room.Key + "-fusion")
// {
// Room = room;
// FusionRoom = new FusionRoom(ipId, Global.ControlSystem, room.Name, "awesomeGuid-" + room.Key);
// FusionRoom.Register();
// FusionRoom.FusionStateChange += new FusionStateEventHandler(FusionRoom_FusionStateChange);
// // Room to fusion room
// room.RoomIsOn.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
// var srcName = FusionRoom.CreateOffsetStringSig(50, "Source - Name", eSigIoMask.InputSigOnly);
// room.CurrentSourceName.LinkInputSig(srcName.InputSig);
// FusionRoom.SystemPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (b) room.RoomOn(null); });
// FusionRoom.SystemPowerOff.OutputSig.UserObject = new Action<bool>(b => { if (b) room.RoomOff(); });
// // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
// FusionRoom.ErrorMessage.InputSig.StringValue = "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;";
// // Sources
// foreach (var src in room.Sources)
// {
// var srcNum = src.Key;
// var pSrc = src.Value as IPresentationSource;
// var keyNum = ExtractNumberFromKey(pSrc.Key);
// if (keyNum == -1)
// {
// Debug.Console(1, this, "WARNING: Cannot link source '{0}' to numbered Fusion attributes", pSrc.Key);
// continue;
// }
// string attrName = null;
// uint attrNum = Convert.ToUInt32(keyNum);
// switch (pSrc.Type)
// {
// case PresentationSourceType.None:
// break;
// case PresentationSourceType.SetTopBox:
// attrName = "Source - TV " + keyNum;
// attrNum += 115; // TV starts at 116
// break;
// case PresentationSourceType.Dvd:
// attrName = "Source - DVD " + keyNum;
// attrNum += 120; // DVD starts at 121
// break;
// case PresentationSourceType.PC:
// attrName = "Source - PC " + keyNum;
// attrNum += 110; // PC starts at 111
// break;
// case PresentationSourceType.Laptop:
// attrName = "Source - Laptop " + keyNum;
// attrNum += 100; // Laptops start at 101
// break;
// case PresentationSourceType.VCR:
// attrName = "Source - VCR " + keyNum;
// attrNum += 125; // VCRs start at 126
// break;
// }
// if (attrName == null)
// {
// Debug.Console(1, this, "Source type {0} does not have corresponsing Fusion attribute type, skipping", pSrc.Type);
// continue;
// }
// Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", attrName, attrNum, pSrc.Key);
// var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputOutputSig);
// // Need feedback when this source is selected
// // Event handler, added below, will compare source changes with this sig dict
// SourceToFeedbackSigs.Add(pSrc, sigD.InputSig);
// // And respond to selection in Fusion
// sigD.OutputSig.UserObject = new Action<bool>(b => { if(b) room.SelectSource(pSrc); });
// }
// // Attach to all room's devices with monitors.
// //foreach (var dev in DeviceManager.Devices)
// foreach (var dev in DeviceManager.GetDevices())
// {
// if (!(dev is ICommunicationMonitor))
// continue;
// var keyNum = ExtractNumberFromKey(dev.Key);
// if (keyNum == -1)
// {
// Debug.Console(1, this, "WARNING: Cannot link device '{0}' to numbered Fusion monitoring attributes", dev.Key);
// continue;
// }
// string attrName = null;
// uint attrNum = Convert.ToUInt32(keyNum);
// //if (dev is SmartGraphicsTouchpanelControllerBase)
// //{
// // if (attrNum > 10)
// // continue;
// // attrName = "Device Ok - Touch Panel " + attrNum;
// // attrNum += 200;
// //}
// //// add xpanel here
// //else
// if (dev is DisplayBase)
// {
// if (attrNum > 10)
// continue;
// attrName = "Device Ok - Display " + attrNum;
// attrNum += 240;
// }
// //else if (dev is DvdDeviceBase)
// //{
// // if (attrNum > 5)
// // continue;
// // attrName = "Device Ok - DVD " + attrNum;
// // attrNum += 260;
// //}
// // add set top box
// // add Cresnet roll-up
// // add DM-devices roll-up
// if (attrName != null)
// {
// // Link comm status to sig and update
// var sigD = FusionRoom.CreateOffsetBoolSig(attrNum, attrName, eSigIoMask.InputSigOnly);
// var smd = dev as ICommunicationMonitor;
// sigD.InputSig.BoolValue = smd.CommunicationMonitor.Status == MonitorStatus.IsOk;
// smd.CommunicationMonitor.StatusChange += (o, a) => { sigD.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
// Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", dev.Key, attrName);
// }
// }
// // Don't think we need to get current status of this as nothing should be alive yet.
// room.PresentationSourceChange += Room_PresentationSourceChange;
// // these get used in multiple places
// var display = room.Display;
// var dispPowerOnAction = new Action<bool>(b => { if (!b) display.PowerOn(); });
// var dispPowerOffAction = new Action<bool>(b => { if (!b) display.PowerOff(); });
// // Display to fusion room sigs
// FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
// FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
// display.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
// if (display is IDisplayUsage)
// (display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
// // Roll up ALL device errors
// ErrorMessageRollUp = new StatusMonitorCollection(this);
// foreach (var dev in DeviceManager.GetDevices())
// {
// var md = dev as ICommunicationMonitor;
// if (md != null)
// {
// ErrorMessageRollUp.AddMonitor(md.CommunicationMonitor);
// Debug.Console(2, this, "Adding '{0}' to room's overall error monitor", md.CommunicationMonitor.Parent.Key);
// }
// }
// ErrorMessageRollUp.Start();
// FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message;
// ErrorMessageRollUp.StatusChange += (o, a) => {
// FusionRoom.ErrorMessage.InputSig.StringValue = ErrorMessageRollUp.Message; };
// // static assets --------------- testing
// // test assets --- THESE ARE BOTH WIRED TO AssetUsage somewhere internally.
// var ta1 = FusionRoom.CreateStaticAsset(1, "Test asset 1", "Awesome Asset", "Awesome123");
// ta1.AssetError.InputSig.StringValue = "This should be error";
// var ta2 = FusionRoom.CreateStaticAsset(2, "Test asset 2", "Awesome Asset", "Awesome1232");
// ta2.AssetUsage.InputSig.StringValue = "This should be usage";
// // Make a display asset
// var dispAsset = FusionRoom.CreateStaticAsset(3, display.Name, "Display", "awesomeDisplayId" + room.Key);
// dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
// dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
// display.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// // NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// // Use extension methods
// dispAsset.TrySetMakeModel(display);
// dispAsset.TryLinkAssetErrorToCommunication(display);
// // Make it so!
// FusionRVI.GenerateFileForAllFusionDevices();
// }
// /// <summary>
// /// Helper to get the number from the end of a device's key string
// /// </summary>
// /// <returns>-1 if no number matched</returns>
// int ExtractNumberFromKey(string key)
// {
// var capture = System.Text.RegularExpressions.Regex.Match(key, @"\D+(\d+)");
// if (!capture.Success)
// return -1;
// else return Convert.ToInt32(capture.Groups[1].Value);
// }
// void Room_PresentationSourceChange(object sender, EssentialsRoomSourceChangeEventArgs e)
// {
// if (e.OldSource != null)
// {
// if (SourceToFeedbackSigs.ContainsKey(e.OldSource))
// SourceToFeedbackSigs[e.OldSource].BoolValue = false;
// }
// if (e.NewSource != null)
// {
// if (SourceToFeedbackSigs.ContainsKey(e.NewSource))
// SourceToFeedbackSigs[e.NewSource].BoolValue = true;
// }
// }
// void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args)
// {
// // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors,
// // even though they all contain sigs.
// var sigData = (args.UserConfiguredSigDetail as BooleanSigDataFixedName);
// if (sigData != null)
// {
// var outSig = sigData.OutputSig;
// if (outSig.UserObject is Action<bool>)
// (outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
// else if (outSig.UserObject is Action<ushort>)
// (outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
// else if (outSig.UserObject is Action<string>)
// (outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
// return;
// }
// var attrData = (args.UserConfiguredSigDetail as BooleanSigData);
// if (attrData != null)
// {
// var outSig = attrData.OutputSig;
// if (outSig.UserObject is Action<bool>)
// (outSig.UserObject as Action<bool>).Invoke(outSig.BoolValue);
// else if (outSig.UserObject is Action<ushort>)
// (outSig.UserObject as Action<ushort>).Invoke(outSig.UShortValue);
// else if (outSig.UserObject is Action<string>)
// (outSig.UserObject as Action<string>).Invoke(outSig.StringValue);
// return;
// }
// }
// }
// public static class FusionRoomExtensions
// {
// /// <summary>
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
// /// FusionRoom.AddSig with join number - 49
// /// </summary>
// /// <returns>The new attribute</returns>
// public static BooleanSigData CreateOffsetBoolSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
// {
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
// number -= 49;
// fr.AddSig(eSigType.Bool, number, name, mask);
// return fr.UserDefinedBooleanSigDetails[number];
// }
// /// <summary>
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
// /// FusionRoom.AddSig with join number - 49
// /// </summary>
// /// <returns>The new attribute</returns>
// public static UShortSigData CreateOffsetUshortSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
// {
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
// number -= 49;
// fr.AddSig(eSigType.UShort, number, name, mask);
// return fr.UserDefinedUShortSigDetails[number];
// }
// /// <summary>
// /// Creates and returns a fusion attribute. The join number will match the established Simpl
// /// standard of 50+, and will generate a 50+ join in the RVI. It calls
// /// FusionRoom.AddSig with join number - 49
// /// </summary>
// /// <returns>The new attribute</returns>
// public static StringSigData CreateOffsetStringSig(this FusionRoom fr, uint number, string name, eSigIoMask mask)
// {
// if (number < 50) throw new ArgumentOutOfRangeException("number", "Cannot be less than 50");
// number -= 49;
// fr.AddSig(eSigType.String, number, name, mask);
// return fr.UserDefinedStringSigDetails[number];
// }
// /// <summary>
// /// Creates and returns a static asset
// /// </summary>
// /// <returns>the new asset</returns>
// public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type, string instanceId)
// {
// fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
// return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
// }
// }
// //************************************************************************************************
// /// <summary>
// /// Extensions to enhance Fusion room, asset and signal creation.
// /// </summary>
// public static class FusionStaticAssetExtensions
// {
// /// <summary>
// /// Tries to set a Fusion asset with the make and model of a device.
// /// If the provided Device is IMakeModel, will set the corresponding parameters on the fusion static asset.
// /// Otherwise, does nothing.
// /// </summary>
// public static void TrySetMakeModel(this FusionStaticAsset asset, Device device)
// {
// var mm = device as IMakeModel;
// if (mm != null)
// {
// asset.ParamMake.Value = mm.DeviceMake;
// asset.ParamModel.Value = mm.DeviceModel;
// }
// }
// /// <summary>
// /// Tries to attach the AssetError input on a Fusion asset to a Device's
// /// CommunicationMonitor.StatusChange event. Does nothing if the device is not
// /// IStatusMonitor
// /// </summary>
// /// <param name="asset"></param>
// /// <param name="device"></param>
// public static void TryLinkAssetErrorToCommunication(this FusionStaticAsset asset, Device device)
// {
// if (device is ICommunicationMonitor)
// {
// var monitor = (device as ICommunicationMonitor).CommunicationMonitor;
// monitor.StatusChange += (o, a) =>
// {
// // Link connected and error inputs on asset
// asset.Connected.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
// asset.AssetError.InputSig.StringValue = a.Status.ToString();
// };
// // set current value
// asset.Connected.InputSig.BoolValue = monitor.Status == MonitorStatus.IsOk;
// asset.AssetError.InputSig.StringValue = monitor.Status.ToString();
// }
// }
// }
//}

View File

@@ -0,0 +1,42 @@
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using Crestron.SimplSharpPro;
//using PepperDash.Essentials.Core.Http;
using PepperDash.Essentials.License;
namespace PepperDash.Essentials.Core
{
public static class Global
{
public static CrestronControlSystem ControlSystem { get; set; }
public static LicenseManager LicenseManager { get; set; }
//public static EssentialsHttpServer HttpConfigServer
//{
// get
// {
// if (_HttpConfigServer == null)
// _HttpConfigServer = new EssentialsHttpServer();
// return _HttpConfigServer;
// }
//}
//static EssentialsHttpServer _HttpConfigServer;
static Global()
{
// Fire up CrestronDataStoreStatic
var err = CrestronDataStoreStatic.InitCrestronDataStore();
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
CrestronConsole.PrintLine("Error starting CrestronDataStoreStatic: {0}", err);
return;
}
}
}
}

View File

@@ -16,9 +16,6 @@ namespace PepperDash.Essentials.Core
///
/// </summary>
/// <param name="act"></param>
/// <summary>
/// AddAction method
/// </summary>
public static void AddAction(Action act)
{
@@ -29,9 +26,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
/// <param name="key"></param>
/// <param name="act"></param>
/// <summary>
/// AddJobTimerItem method
/// </summary>
public static void AddJobTimerItem(JobTimerItem item)
{
var existing = Items.FirstOrDefault(i => i.Key == item.Key);
@@ -57,9 +51,9 @@ namespace PepperDash.Essentials.Core
}
}
/// <summary>
/// Represents a JobTimerItem
/// </summary>
/// <summary>
///
/// </summary>
public class JobTimerItem
{
public string Key { get; private set; }
@@ -78,7 +72,6 @@ namespace PepperDash.Essentials.Core
public enum eJobTimerCycleTypes
{
RunEveryDay,
RunEveryHour,
RunEveryHalfHour,
RunEveryMinute

View File

@@ -23,9 +23,9 @@ namespace PepperDash.Essentials.Core
/// </summary>
public BoolFeedback InUseFeedback { get; private set; }
/// <summary>
/// Gets or sets the InUseCountFeedback
/// </summary>
/// <summary>
/// Feedback that changes with the count of users
/// </summary>
public IntFeedback InUseCountFeedback { get; private set; }
public InUseTracking()
@@ -39,9 +39,6 @@ namespace PepperDash.Essentials.Core
/// multiple times, provided that the label is different
/// </summary>
/// <param name="label">A label to identify the instance of the user. Treated like a "role", etc.</param>
/// <summary>
/// AddUser method
/// </summary>
public void AddUser(object objectToAdd, string label)
{
// check if an exact object/label pair exists and ignore if so. No double-registers.
@@ -56,9 +53,9 @@ namespace PepperDash.Essentials.Core
InUseCountFeedback.FireUpdate();
}
/// <summary>
/// RemoveUser method
/// </summary>
/// <summary>
/// Remove a user object from this tracking
/// </summary>
public void RemoveUser(object objectToRemove, string label)
{
// Find the user object if exists and remove it
@@ -73,9 +70,10 @@ namespace PepperDash.Essentials.Core
}
}
/// <summary>
/// Represents a InUseTrackingObject
/// </summary>
/// <summary>
/// Wrapper for label/object pair representing in-use status. Allows the same object to
/// register for in-use with different roles.
/// </summary>
public class InUseTrackingObject
{
public string Label { get; private set; }

View File

@@ -8,24 +8,14 @@ using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Essentials.Core;
using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.License
{
public abstract class LicenseManager
{
/// <summary>
/// Gets or sets the LicenseIsValid
/// </summary>
public BoolFeedback LicenseIsValid { get; protected set; }
/// <summary>
/// Gets or sets the LicenseMessage
/// </summary>
public StringFeedback LicenseMessage { get; protected set; }
/// <summary>
/// Gets or sets the LicenseLog
/// </summary>
public StringFeedback LicenseLog { get; protected set; }
protected LicenseManager()
@@ -39,9 +29,6 @@ namespace PepperDash.Essentials.License
protected abstract string GetStatusString();
}
/// <summary>
/// Represents a MockEssentialsLicenseManager
/// </summary>
public class MockEssentialsLicenseManager : LicenseManager
{
/// <summary>
@@ -62,7 +49,7 @@ namespace PepperDash.Essentials.License
MockEssentialsLicenseManager() : base()
{
LicenseIsValid = new BoolFeedback("LicenseIsValid",
LicenseIsValid = new BoolFeedback(LicenseCue.LicenseIsValid,
() => { return IsValid; });
CrestronConsole.AddNewConsoleCommand(
s => SetFromConsole(s.Equals("true", StringComparison.OrdinalIgnoreCase)),
@@ -82,7 +69,7 @@ namespace PepperDash.Essentials.License
{
IsValid = isValid;
CrestronDataStoreStatic.SetGlobalBoolValue("MockLicense", isValid);
Debug.LogMessage(LogEventLevel.Information, "Mock License is{0} valid", IsValid ? "" : " not");
Debug.Console(0, "Mock License is{0} valid", IsValid ? "" : " not");
LicenseIsValid.FireUpdate();
}
@@ -96,4 +83,16 @@ namespace PepperDash.Essentials.License
return string.Format("License Status: {0}", IsValid ? "Valid" : "Not Valid");
}
}
public class EssentialsLicenseManager
{
}
public class LicenseCue
{
public static Cue LicenseIsValid = Cue.BoolCue("LicenseIsValid", 15991);
public static Cue LicenseMessage = Cue.StringCue("LicenseMessage", 15991);
}
}

View File

@@ -26,10 +26,6 @@ namespace PepperDash.Essentials.Core
Device = device;
}
/// <summary>
/// Start method
/// </summary>
/// <inheritdoc />
public override void Start()
{
Device.OnlineStatusChange -= Device_OnlineStatusChange;
@@ -37,10 +33,6 @@ namespace PepperDash.Essentials.Core
GetStatus();
}
/// <summary>
/// Stop method
/// </summary>
/// <inheritdoc />
public override void Stop()
{
Device.OnlineStatusChange -= Device_OnlineStatusChange;

View File

@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using System.ComponentModel;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Used for monitoring comms that are IBasicCommunication. Will send a poll string and provide an event when
/// statuses change.
/// </summary>
public class GenericCommunicationMonitor : StatusMonitorBase
{
public IBasicCommunication Client { get; private set; }
long PollTime;
CTimer PollTimer;
string PollString;
Action PollAction;
/// <summary>
///
/// </summary>
/// <param name="client"></param>
/// <param name="pollTime">in MS, >= 5000</param>
/// <param name="warningTime">in MS, >= 5000</param>
/// <param name="errorTime">in MS, >= 5000</param>
/// <param name="pollString">String to send to comm</param>
public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, long pollTime,
long warningTime, long errorTime, string pollString) :
base(parent, warningTime, errorTime)
{
if (pollTime > warningTime || pollTime > errorTime)
throw new ArgumentException("pollTime must be less than warning or errorTime");
//if (pollTime < 5000)
// throw new ArgumentException("pollTime cannot be less than 5000 ms");
Client = client;
PollTime = pollTime;
PollString = pollString;
}
/// <summary>
/// Poll is a provided action instead of string
/// </summary>
/// <param name="parent"></param>
/// <param name="client"></param>
/// <param name="pollTime"></param>
/// <param name="warningTime"></param>
/// <param name="errorTime"></param>
/// <param name="pollBytes"></param>
public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client, long pollTime,
long warningTime, long errorTime, Action pollAction) :
base(parent, warningTime, errorTime)
{
if (pollTime > warningTime || pollTime > errorTime)
throw new ArgumentException("pollTime must be less than warning or errorTime");
//if (pollTime < 5000)
// throw new ArgumentException("pollTime cannot be less than 5000 ms");
Client = client;
PollTime = pollTime;
PollAction = pollAction;
}
/// <summary>
/// Build the monitor from a config object
/// </summary>
public GenericCommunicationMonitor(IKeyed parent, IBasicCommunication client,
CommunicationMonitorConfig props) :
this(parent, client, props.PollInterval, props.TimeToWarning, props.TimeToError, props.PollString)
{
}
public override void Start()
{
Client.BytesReceived += Client_BytesReceived;
Poll();
PollTimer = new CTimer(o => Poll(), null, PollTime, PollTime);
}
public override void Stop()
{
Client.BytesReceived -= this.Client_BytesReceived;
PollTimer.Stop();
PollTimer = null;
StopErrorTimers();
}
/// <summary>
/// Upon any receipt of data, set everything to ok!
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Client_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
{
Status = MonitorStatus.IsOk;
ResetErrorTimers();
}
void Poll()
{
StartErrorTimers();
if (Client.IsConnected)
{
//Debug.Console(2, this, "Polling");
if(PollAction != null)
PollAction.Invoke();
else
Client.SendText(PollString);
}
else
{
Debug.Console(2, this, "Comm not connected");
}
}
/// <summary>
/// When the client connects, and we're waiting for it, respond and disconect from event
/// </summary>
void OneTimeConnectHandler(object o, EventArgs a)
{
if (Client.IsConnected)
{
//Client.IsConnected -= OneTimeConnectHandler;
Debug.Console(2, this, "Comm connected");
Poll();
}
}
}
public class CommunicationMonitorConfig
{
public int PollInterval { get; set; }
public int TimeToWarning { get; set; }
public int TimeToError { get; set; }
public string PollString { get; set; }
public CommunicationMonitorConfig()
{
PollInterval = 30000;
TimeToWarning = 120000;
TimeToError = 300000;
PollString = "";
}
}
}

View File

@@ -6,24 +6,20 @@ using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the contract for IStatusMonitor
/// </summary>
public interface IStatusMonitor
{
IKeyed Parent { get; }
event EventHandler<MonitorStatusChangeEventArgs> StatusChange;
MonitorStatus Status { get; }
string Message { get; }
BoolFeedback IsOnlineFeedback { get; set; }
void Start();
void Stop();
}
/// <summary>
/// Defines the contract for ICommunicationMonitor
/// </summary>
/// <summary>
/// Represents a class that has a basic communication monitoring
/// </summary>
public interface ICommunicationMonitor
{
StatusMonitorBase CommunicationMonitor { get; }
@@ -42,15 +38,9 @@ namespace PepperDash.Essentials.Core
public class MonitorStatusChangeEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the Status
/// </summary>
public MonitorStatus Status { get; private set; }
/// <summary>
/// Gets or sets the Message
/// </summary>
public string Message { get; private set; }
public MonitorStatusChangeEventArgs(MonitorStatus status)
{
Status = status;

View File

@@ -18,24 +18,14 @@ namespace PepperDash.Essentials.Core
public event EventHandler<MonitorStatusChangeEventArgs> StatusChange;
/// <summary>
/// Gets or sets the Key
/// Format returned: "parentdevkey-comMonitor"
/// </summary>
public string Key { get { return Parent.Key + "-comMonitor"; } }
/// <summary>
/// Gets or sets the Name
/// </summary>
public string Name { get { return "Comm. monitor"; } }
/// <summary>
/// Gets or sets the Parent
/// </summary>
public IKeyed Parent { get; private set; }
public BoolFeedback IsOnlineFeedback { get; set; }
public bool IsOnline;
public MonitorStatus Status
{
get { return _Status; }
@@ -44,7 +34,6 @@ namespace PepperDash.Essentials.Core
if (value != _Status)
{
_Status = value;
OnStatusChange(value);
}
}
@@ -77,7 +66,6 @@ namespace PepperDash.Essentials.Core
if (warningTime < 5000 || errorTime < 5000)
throw new ArgumentException("time values cannot be less that 5000 ms");
IsOnlineFeedback = new BoolFeedback(() => { return IsOnline; });
Status = MonitorStatus.StatusUnknown;
WarningTime = warningTime;
ErrorTime = errorTime;
@@ -88,11 +76,6 @@ namespace PepperDash.Essentials.Core
protected void OnStatusChange(MonitorStatus status)
{
if (_Status == MonitorStatus.IsOk)
IsOnline = true;
else
IsOnline = false;
IsOnlineFeedback.FireUpdate();
var handler = StatusChange;
if (handler != null)
handler(this, new MonitorStatusChangeEventArgs(status));
@@ -100,11 +83,6 @@ namespace PepperDash.Essentials.Core
protected void OnStatusChange(MonitorStatus status, string message)
{
if (_Status == MonitorStatus.IsOk)
IsOnline = true;
else
IsOnline = false;
IsOnlineFeedback.FireUpdate();
var handler = StatusChange;
if (handler != null)
handler(this, new MonitorStatusChangeEventArgs(status, message));

View File

@@ -26,29 +26,16 @@ namespace PepperDash.Essentials.Core
public event EventHandler<MonitorStatusChangeEventArgs> StatusChange;
/// <summary>
/// Gets or sets the Status
/// </summary>
public MonitorStatus Status { get; protected set; }
/// <summary>
/// Gets or sets the Message
/// </summary>
public string Message { get; private set; }
/// <summary>
/// Gets or sets the IsOnlineFeedback
/// </summary>
public BoolFeedback IsOnlineFeedback { get; set; }
public StatusMonitorCollection(IKeyed parent)
{
Parent = parent;
}
/// <summary>
/// Start method
/// </summary>
public void Start()
{
foreach (var mon in Monitors)
@@ -76,34 +63,30 @@ namespace PepperDash.Essentials.Core
initialStatus = MonitorStatus.InWarning;
prefix = "2:";
}
else if (IsOk.Count() > 0)
else if (InWarning.Count() > 0)
initialStatus = MonitorStatus.IsOk;
else
initialStatus = MonitorStatus.StatusUnknown;
// Build the error message string
if (InError.Count() > 0 || InWarning.Count() > 0)
{
StringBuilder sb = new StringBuilder(prefix);
if (InError.Count() > 0)
{
// Do string splits and joins
sb.Append(string.Format("{0} Errors:", InError.Count()));
foreach (var mon in InError)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
if (InWarning.Count() > 0)
{
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
foreach (var mon in InWarning)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
Message = sb.ToString();
}
else
{
Message = "Room Ok.";
}
if (InError.Count() > 0 || InWarning.Count() > 0)
{
StringBuilder sb = new StringBuilder(prefix);
if (InError.Count() > 0)
{
// Do string splits and joins
sb.Append(string.Format("{0} Errors:", InError.Count()));
foreach (var mon in InError)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
if (InWarning.Count() > 0)
{
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
foreach (var mon in InWarning)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
Message = sb.ToString();
}
// Want to fire even if status doesn't change because the message may.
Status = initialStatus;
@@ -116,9 +99,6 @@ namespace PepperDash.Essentials.Core
ProcessStatuses();
}
/// <summary>
/// Stop method
/// </summary>
public void Stop()
{
throw new NotImplementedException();
@@ -126,9 +106,6 @@ namespace PepperDash.Essentials.Core
#endregion
/// <summary>
/// AddMonitor method
/// </summary>
public void AddMonitor(IStatusMonitor monitor)
{
if (!Monitors.Contains(monitor))

View File

@@ -0,0 +1,231 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepperDash.Essentials.Core</RootNamespace>
<AssemblyName>PepperDash_Essentials_Core</AssemblyName>
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92300};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
<PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
<OSVersion>5.0</OSVersion>
<DeployDirSuffix>SmartDeviceProject1</DeployDirSuffix>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<NativePlatformName>Windows CE</NativePlatformName>
<FormFactorID>
</FormFactorID>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowedReferenceRelatedFileExtensions>.allowedReferenceRelatedFileExtensions</AllowedReferenceRelatedFileExtensions>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<FileAlignment>512</FileAlignment>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowedReferenceRelatedFileExtensions>.allowedReferenceRelatedFileExtensions</AllowedReferenceRelatedFileExtensions>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<FileAlignment>512</FileAlignment>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
</PropertyGroup>
<ItemGroup>
<Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.DM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.EthernetCommunications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.Fusion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.Remotes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.0.16459, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\pepperdash-simplsharp-core\Pepperdash Core\CLZ Builds\PepperDash_Core.dll</HintPath>
</Reference>
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath>
</Reference>
<Reference Include="SimplSharpPro, Version=1.5.0.7, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="Devices\CodecInterfaces.cs" />
<Compile Include="Global\JobTimer.cs" />
<Compile Include="Ramps and Increments\ActionIncrementer.cs" />
<Compile Include="Comm and IR\CommFactory.cs" />
<Compile Include="Comm and IR\CommunicationExtras.cs" />
<Compile Include="Comm and IR\REMOVE ComPortConfig.cs" />
<Compile Include="Comm and IR\ComSpecJsonConverter.cs" />
<Compile Include="Comm and IR\ConsoleCommMockDevice.cs" />
<Compile Include="Comm and IR\IRPortHelper.cs" />
<Compile Include="Config\BasicConfig.cs" />
<Compile Include="Config\ConfigPropertiesHelpers.cs" />
<Compile Include="Config\InfoConfig.cs" />
<Compile Include="Config\DeviceConfig.cs" />
<Compile Include="Constants\CommonCues.cs" />
<Compile Include="Devices\DisplayUiConstants.cs" />
<Compile Include="Devices\IUsageTracking.cs" />
<Compile Include="Devices\DeviceJsonApi.cs" />
<Compile Include="Devices\SourceListItem.cs" />
<Compile Include="DeviceTypeInterfaces\IDisplayBasic.cs" />
<Compile Include="DeviceTypeInterfaces\IDumbSource.cs" />
<Compile Include="DeviceTypeInterfaces\IWarmingCooling.cs" />
<Compile Include="DeviceTypeInterfaces\IDiscPlayerControls.cs" />
<Compile Include="DeviceTypeInterfaces\IPower.cs" />
<Compile Include="DeviceTypeInterfaces\IUiDisplayInfo.cs" />
<Compile Include="DeviceTypeInterfaces\ISetTopBoxControls.cs" />
<Compile Include="DeviceTypeInterfaces\IChannel.cs" />
<Compile Include="DeviceTypeInterfaces\IColorFunctions.cs" />
<Compile Include="DeviceTypeInterfaces\IDPad.cs" />
<Compile Include="DeviceTypeInterfaces\IDvr.cs" />
<Compile Include="DeviceTypeInterfaces\Template.cs" />
<Compile Include="DeviceTypeInterfaces\ITransport.cs" />
<Compile Include="Devices\GenericMonitoredTcpDevice.cs" />
<Compile Include="DeviceTypeInterfaces\INumeric.cs" />
<Compile Include="Devices\IVolumeAndAudioInterfaces.cs" />
<Compile Include="Display\BasicIrDisplay.cs" />
<Compile Include="Feedbacks\BoolFeedbackOneShot.cs" />
<Compile Include="Ramps and Increments\NumericalHelpers.cs" />
<Compile Include="Ramps and Increments\UshortSigIncrementer.cs" />
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
<Compile Include="Routing\ICardPortsDevice.cs" />
<Compile Include="InUseTracking\IInUseTracking.cs" />
<Compile Include="InUseTracking\InUseTracking.cs" />
<Compile Include="Routing\IRoutingInputsExtensions.cs" />
<Compile Include="Monitoring\StatusMonitorCollection.cs" />
<Compile Include="Monitoring\CrestronGenericBaseCommunicationMonitor.cs" />
<Compile Include="Monitoring\StatusMonitorBase.cs" />
<Compile Include="Monitoring\Interfaces and things.cs" />
<Compile Include="Monitoring\GenericCommunicationMonitor.cs" />
<Compile Include="Devices\NewInterfaces.cs" />
<Compile Include="Devices\IAttachVideoStatusExtensions.cs" />
<Compile Include="Devices\IHasFeedbacks.cs" />
<Compile Include="Devices\SmartObjectBaseTypes.cs" />
<Compile Include="Devices\PresentationDeviceType.cs" />
<Compile Include="Display\DELETE IRDisplayBase.cs" />
<Compile Include="Display\MockDisplay.cs" />
<Compile Include="Ethernet\EthernetStatistics.cs" />
<Compile Include="Fusion\MOVED FusionSystemController.cs" />
<Compile Include="Global\Global.cs" />
<Compile Include="License\EssentialsLicenseManager.cs" />
<Compile Include="Feedbacks\BoolOutputLogicals.cs" />
<Compile Include="Presets\Interfaces.cs" />
<Compile Include="Presets\PresetsListSubpageReferenceListItem.cs" />
<Compile Include="Presets\DevicePresetsView.cs" />
<Compile Include="Presets\PresetChannel.cs" />
<Compile Include="Presets\DevicePresets.cs" />
<Compile Include="Routing\RoutingInterfaces.cs" />
<Compile Include="Routing\RoutingPort.cs" />
<Compile Include="Routing\RoutingPortCollection.cs" />
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
<Compile Include="Routing\RoutingPortNames.cs" />
<Compile Include="Routing\TieLineConfig.cs" />
<Compile Include="SmartObjects\SmartObjectNumeric.cs" />
<Compile Include="SmartObjects\SmartObjectDynamicList.cs" />
<Compile Include="SmartObjects\SmartObjectDPad.cs" />
<Compile Include="SmartObjects\SmartObjectHelper.cs" />
<Compile Include="SmartObjects\SmartObjectHelperBase.cs" />
<Compile Include="Routing\TieLine.cs" />
<Compile Include="Timers\CountdownTimer.cs" />
<Compile Include="Touchpanels\Keyboards\HabaneroKeyboardController.cs" />
<Compile Include="Touchpanels\MOVED LargeTouchpanelControllerBase.cs" />
<Compile Include="Touchpanels\TriListExtensions.cs" />
<Compile Include="Touchpanels\MOVED UIControllers\DevicePageControllerBase.cs" />
<Compile Include="UI PageManagers\BlurayPageManager.cs" />
<Compile Include="UI PageManagers\SetTopBoxThreePanelPageManager.cs" />
<Compile Include="UI PageManagers\SinglePageManager.cs" />
<Compile Include="UI PageManagers\PageManager.cs" />
<Compile Include="UI PageManagers\SetTopBoxTwoPanelPageManager.cs" />
<Compile Include="VideoStatus\VideoStatusOutputs.cs" />
<Compile Include="VideoStatus\VideoStatusCues.cs" />
<Compile Include="Cues and DevAction\Cues.cs" />
<Compile Include="Comm and IR\ComPortController.cs" />
<Compile Include="Crestron\CrestronGenericBaseDevice.cs" />
<Compile Include="Debug\Debug.cs" />
<Compile Include="DeviceControlsParentInterfaces\IPresentationSource.cs" />
<Compile Include="Devices\DeviceManager.cs" />
<Compile Include="Devices\IrOutputPortController.cs" />
<Compile Include="Display\DisplayBase.cs" />
<Compile Include="Feedbacks\Feedbacks.cs" />
<Compile Include="Room\Room.cs" />
<Compile Include="Room\RoomCues.cs" />
<Compile Include="Room\MOVED RoomEventArgs.cs" />
<Compile Include="SmartObjects\SubpageReferencList\SourceListSubpageReferenceList.cs" />
<Compile Include="Touchpanels\ModalDialog.cs" />
<Compile Include="Touchpanels\SmartGraphicsTouchpanelControllerBase.cs" />
<Compile Include="TriListBridges\HandlerBridge.cs" />
<Compile Include="Devices\FIND HOMES Interfaces.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SigHelper.cs" />
<Compile Include="REMOVE SigId.cs" />
<Compile Include="SmartObjects\SubpageReferencList\SubpageReferenceList.cs" />
<Compile Include="SmartObjects\SubpageReferencList\SubpageReferenceListItem.cs" />
<None Include="app.config" />
<None Include="Properties\ControlSystem.cfg" />
</ItemGroup>
<ItemGroup>
<Folder Include="bin\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
</VisualStudio>
</ProjectExtensions>
<PropertyGroup>
<PostBuildEvent>rem S# Pro preparation will execute after these operations</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
//using SSMono.IO;
namespace PepperDash.Essentials.Core.Presets
{
/// <summary>
/// Class that represents the model behind presets display
/// </summary>
public class DevicePresetsModel : Device
{
public event EventHandler PresetsLoaded;
public int PulseTime { get; set; }
public int DigitSpacingMS { get; set; }
public bool PresetsAreLoaded { get; private set; }
public List<PresetChannel> PresetsList { get { return _PresetsList.ToList(); } }
List<PresetChannel> _PresetsList;
public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } }
public bool UseLocalImageStorage { get; set; }
public string ImagesLocalHostPrefix { get; set; }
public string ImagesPathPrefix { get; set; }
public string ListPathPrefix { get; set; }
/// <summary>
/// The methods on the STB device to call when dialing
/// </summary>
Dictionary<char, Action<bool>> DialFunctions;
Action<bool> EnterFunction;
bool DialIsRunning;
string FilePath;
bool InitSuccess;
//SSMono.IO.FileSystemWatcher ListWatcher;
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
: base(key)
{
PulseTime = 150;
DigitSpacingMS = 150;
try
{
// Grab the digit functions from the device
// If any fail, the whole thing fails peacefully
DialFunctions = new Dictionary<char, Action<bool>>(10)
{
{ '1', setTopBox.Digit1 },
{ '2', setTopBox.Digit2 },
{ '3', setTopBox.Digit3 },
{ '4', setTopBox.Digit4 },
{ '5', setTopBox.Digit5 },
{ '6', setTopBox.Digit6 },
{ '7', setTopBox.Digit7 },
{ '8', setTopBox.Digit8 },
{ '9', setTopBox.Digit9 },
{ '0', setTopBox.Digit0 },
{ '-', setTopBox.Dash }
};
}
catch
{
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
DialFunctions = null;
return;
}
EnterFunction = setTopBox.KeypadEnter;
UseLocalImageStorage = true;
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0);
ImagesPathPrefix = @"/presets/images.zip/";
ListPathPrefix = @"/html/presets/lists/";
SetFileName(fileName);
//ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists");
//ListWatcher.NotifyFilter = NotifyFilters.LastWrite;
//ListWatcher.EnableRaisingEvents = true;
//ListWatcher.Changed += ListWatcher_Changed;
InitSuccess = true;
}
public void SetFileName(string path)
{
FilePath = ListPathPrefix + path;
LoadChannels();
}
public void LoadChannels()
{
PresetsAreLoaded = false;
try
{
var pl = JsonConvert.DeserializeObject<PresetsList>(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII));
Name = pl.Name;
_PresetsList = pl.Channels;
}
catch (Exception e)
{
Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message);
// Just save a default empty list
_PresetsList = new List<PresetChannel>();
}
PresetsAreLoaded = true;
var handler = PresetsLoaded;
if (handler != null)
handler(this, EventArgs.Empty);
}
public void Dial(int presetNum)
{
if (presetNum <= _PresetsList.Count)
Dial(_PresetsList[presetNum - 1].Channel);
}
public void Dial(string chanNum)
{
if (DialIsRunning || !InitSuccess) return;
if (DialFunctions == null)
{
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
return;
}
DialIsRunning = true;
CrestronInvoke.BeginInvoke(o =>
{
foreach (var c in chanNum.ToCharArray())
{
if (DialFunctions.ContainsKey(c))
Pulse(DialFunctions[c]);
CrestronEnvironment.Sleep(DigitSpacingMS);
}
if (EnterFunction != null)
Pulse(EnterFunction);
DialIsRunning = false;
});
}
void Pulse(Action<bool> act)
{
act(true);
CrestronEnvironment.Sleep(PulseTime);
act(false);
}
/// <summary>
/// Event handler for filesystem watcher. When directory changes, this is called
/// </summary>
//void ListWatcher_Changed(object sender, FileSystemEventArgs e)
//{
// Debug.Console(1, this, "folder modified: {0}", e.FullPath);
// if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase))
// {
// Debug.Console(1, this, "File changed: {0}", e.ChangeType);
// LoadChannels();
// }
//}
}
}

View File

@@ -8,31 +8,13 @@ using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials.Core.Presets
{
/// <summary>
/// Represents a DevicePresetsView
/// </summary>
public class DevicePresetsView
{
/// <summary>
/// Gets or sets the ShowNumbers
/// </summary>
public bool ShowNumbers { get; set; }
/// <summary>
/// Gets or sets the ShowName
/// </summary>
public bool ShowName { get; set; }
/// <summary>
/// Gets or sets the ShowIcon
/// </summary>
public bool ShowIcon { get; set; }
/// <summary>
/// Gets or sets the SRL
/// </summary>
public SubpageReferenceList SRL { get; private set; }
/// <summary>
/// Gets or sets the Model
/// </summary>
public DevicePresetsModel Model { get; private set; }
public DevicePresetsView(BasicTriListWithSmartObject tl, DevicePresetsModel model)
@@ -50,9 +32,6 @@ namespace PepperDash.Essentials.Core.Presets
Model.PresetsLoaded += new EventHandler(Model_PresetsLoaded);
}
/// <summary>
/// Attach method
/// </summary>
public void Attach()
{
if (Model.PresetsAreLoaded)
@@ -67,9 +46,6 @@ namespace PepperDash.Essentials.Core.Presets
}
}
/// <summary>
/// Detach method
/// </summary>
public void Detach()
{
SRL.Clear();

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core.Presets
{
public class PresetChannel
{
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonProperty(Required = Required.Always)]
public string IconUrl { get; set; }
[JsonProperty(Required = Required.Always)]
public string Channel { get; set; }
}
public class PresetsList
{
[JsonProperty(Required=Required.Always)]
public string Name { get; set; }
[JsonProperty(Required = Required.Always)]
public List<PresetChannel> Channels { get; set; }
}
}

View File

@@ -7,14 +7,10 @@ using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using Serilog.Events;
namespace PepperDash.Essentials.Core.Presets
{
/// <summary>
/// Represents a PresetsListSubpageReferenceListItem
/// </summary>
public class PresetsListSubpageReferenceListItem : SubpageReferenceListItem
{
DevicePresetsView View;
@@ -30,10 +26,6 @@ namespace PepperDash.Essentials.Core.Presets
Refresh();
}
/// <summary>
/// Clear method
/// </summary>
/// <inheritdoc />
public override void Clear()
{
Owner.GetBoolFeedbackSig(Index, 1).UserObject = null;
@@ -42,10 +34,6 @@ namespace PepperDash.Essentials.Core.Presets
Owner.StringInputSig(Index, 3).StringValue = "";
}
/// <summary>
/// Refresh method
/// </summary>
/// <inheritdoc />
public override void Refresh()
{
var name = View.ShowName ? Channel.Name : "";
@@ -53,7 +41,7 @@ namespace PepperDash.Essentials.Core.Presets
var chan = View.ShowNumbers ? Channel.Channel : "";
Owner.StringInputSig(Index, 2).StringValue = chan;
var url = View.Model.ImagesLocalHostPrefix + View.Model.ImagesPathPrefix + Channel.IconUrl;
Debug.LogMessage(LogEventLevel.Verbose, "icon url={0}", url);
Debug.Console(2, "icon url={0}", url);
var icon = View.ShowIcon ? url : "";
Owner.StringInputSig(Index, 3).StringValue = icon;
}

View File

@@ -0,0 +1,8 @@
using System.Reflection;
[assembly: AssemblyTitle("PepperDashEssentialsBase")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PepperDashEssentialsBase")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyVersion("1.0.0.*")]

View File

@@ -0,0 +1,37 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharpPro;
//namespace PepperDash.Essentials.Core
//{
// public class SigId
// {
// public uint Number { get; private set; }
// public eSigType Type { get; private set; }
// public SigId(eSigType type, uint number)
// {
// Type = type;
// Number = number;
// }
// public override bool Equals(object id)
// {
// if (id is SigId)
// {
// var sigId = id as SigId;
// return this.Number == sigId.Number && this.Type == sigId.Type;
// }
// else
// return base.Equals(id);
// }
// public override int GetHashCode()
// {
// return base.GetHashCode();
// }
// }
//}

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