mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-23 09:25:00 +00:00
Compare commits
2 Commits
v2.4.5
...
feature/Ge
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbba6e089a | ||
|
|
cef78c881e |
23
.github/scripts/GenerateVersionNumber-2.0.0.ps1
vendored
23
.github/scripts/GenerateVersionNumber-2.0.0.ps1
vendored
@@ -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
|
|
||||||
@@ -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
|
|
||||||
141
.github/workflows/docker.yml
vendored
Normal file
141
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
name: Branch Build Using Docker
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- feature/*
|
||||||
|
- hotfix/*
|
||||||
|
- bugfix/*
|
||||||
|
- release/*
|
||||||
|
- development
|
||||||
|
|
||||||
|
env:
|
||||||
|
# solution path doesn't need slashes unless it is multiple folders deep
|
||||||
|
# solution name does not include extension. .sln is assumed
|
||||||
|
SOLUTION_PATH: PepperDashEssentials
|
||||||
|
SOLUTION_FILE: PepperDashEssentials
|
||||||
|
# Do not edit this, we're just creating it here
|
||||||
|
VERSION: 0.0.0-buildtype-buildnumber
|
||||||
|
# Defaults to debug for build type
|
||||||
|
BUILD_TYPE: Debug
|
||||||
|
# Defaults to main as the release branch. Change as necessary
|
||||||
|
RELEASE_BRANCH: main
|
||||||
|
jobs:
|
||||||
|
Build_Project:
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
# First we checkout the source repo
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
# Fetch all tags
|
||||||
|
- name: Fetch tags
|
||||||
|
run: git fetch --tags
|
||||||
|
# Generate the appropriate version number
|
||||||
|
- name: Set Version Number
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
$version = ./.github/scripts/GenerateVersionNumber.ps1
|
||||||
|
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
# Use the version number to set the version of the assemblies
|
||||||
|
- name: Update AssemblyInfo.cs
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
|
||||||
|
- name: restore Nuget Packages
|
||||||
|
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
|
||||||
|
# Login to Docker
|
||||||
|
- name: Login to Docker
|
||||||
|
uses: azure/docker-login@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
# Build the solutions in the docker image
|
||||||
|
- name: Build Solution
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
|
||||||
|
# Zip up the output files as needed
|
||||||
|
- name: Zip Build Output
|
||||||
|
shell: powershell
|
||||||
|
run: ./.github/scripts/ZipBuildOutput.ps1
|
||||||
|
# Write the version to a file to be consumed by the push jobs
|
||||||
|
- name: Write Version
|
||||||
|
run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt"
|
||||||
|
# Upload the build output as an artifact
|
||||||
|
- name: Upload Build Output
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Build
|
||||||
|
path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||||
|
# Upload the Version file as an artifact
|
||||||
|
- name: Upload version.txt
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Version
|
||||||
|
path: ${{env.GITHUB_HOME}}\output\version.txt
|
||||||
|
- name: Create Release
|
||||||
|
id: create_release
|
||||||
|
# using contributor's version to allow for pointing at the right commit
|
||||||
|
uses: fleskesvor/create-release@feature/support-target-commitish
|
||||||
|
with:
|
||||||
|
tag_name: ${{ env.VERSION }}
|
||||||
|
release_name: ${{ env.VERSION }}
|
||||||
|
prerelease: ${{contains('debug', env.BUILD_TYPE)}}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
# Upload the build package to the release
|
||||||
|
- name: Upload Release Package
|
||||||
|
id: upload_release
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
with:
|
||||||
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||||
|
asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
Push_Nuget_Package:
|
||||||
|
needs: Build_Project
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
- name: Download Build Version Info
|
||||||
|
uses: actions/download-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Version
|
||||||
|
- name: Set Version Number
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Get-ChildItem "./Version"
|
||||||
|
$version = Get-Content -Path ./Version/version.txt
|
||||||
|
Write-Host "Version: $version"
|
||||||
|
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
Remove-Item -Path ./Version/version.txt
|
||||||
|
Remove-Item -Path ./Version
|
||||||
|
- name: Download Build output
|
||||||
|
uses: actions/download-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Build
|
||||||
|
path: ./
|
||||||
|
- name: Unzip Build file
|
||||||
|
run: |
|
||||||
|
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||||
|
Remove-Item -Path .\*.zip
|
||||||
|
- name: Copy Files to root & delete output directory
|
||||||
|
run: |
|
||||||
|
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||||
|
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||||
|
Remove-Item -Path .\output -Recurse
|
||||||
|
- name: Add nuget.exe
|
||||||
|
uses: nuget/setup-nuget@v1
|
||||||
|
- name: Add Github Packages source
|
||||||
|
run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Add nuget.org API Key
|
||||||
|
run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
|
||||||
|
- name: Create nuget package
|
||||||
|
run: nuget pack "./PepperDash_Essentials_Core.nuspec" -version ${{ env.VERSION }}
|
||||||
|
- name: Publish nuget package to Github registry
|
||||||
|
run: nuget push **/*.nupkg -source github
|
||||||
|
- name: Publish nuget package to nuget.org
|
||||||
|
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
|
||||||
125
.github/workflows/main.yml
vendored
Normal file
125
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
name: main Build using Docker
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types:
|
||||||
|
- created
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
env:
|
||||||
|
# solution path doesn't need slashes unless there it is multiple folders deep
|
||||||
|
# solution name does not include extension. .sln is assumed
|
||||||
|
SOLUTION_PATH: PepperDashEssentials
|
||||||
|
SOLUTION_FILE: PepperDashEssentials
|
||||||
|
# Do not edit this, we're just creating it here
|
||||||
|
VERSION: 0.0.0-buildtype-buildnumber
|
||||||
|
# Defaults to debug for build type
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
# Defaults to main as the release branch. Change as necessary
|
||||||
|
RELEASE_BRANCH: main
|
||||||
|
jobs:
|
||||||
|
Build_Project:
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
# First we checkout the source repo
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
# Generate the appropriate version number
|
||||||
|
- name: Set Version Number
|
||||||
|
shell: powershell
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.event.release.tag_name }}
|
||||||
|
run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
# Use the version number to set the version of the assemblies
|
||||||
|
- name: Update AssemblyInfo.cs
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
|
||||||
|
- name: restore Nuget Packages
|
||||||
|
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
|
||||||
|
# Login to Docker
|
||||||
|
- name: Login to Docker
|
||||||
|
uses: azure/docker-login@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
# Build the solutions in the docker image
|
||||||
|
- name: Build Solution
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
|
||||||
|
# Zip up the output files as needed
|
||||||
|
- name: Zip Build Output
|
||||||
|
shell: powershell
|
||||||
|
run: ./.github/scripts/ZipBuildOutput.ps1
|
||||||
|
# Write the version to a file to be consumed by the push jobs
|
||||||
|
- name: Write Version
|
||||||
|
run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt"
|
||||||
|
# Upload the build output as an artifact
|
||||||
|
- name: Upload Build Output
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Build
|
||||||
|
path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||||
|
# Upload the Version file as an artifact
|
||||||
|
- name: Upload version.txt
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Version
|
||||||
|
path: ${{env.GITHUB_HOME}}\output\version.txt
|
||||||
|
# Upload the build package to the release
|
||||||
|
- name: Upload Release Package
|
||||||
|
id: upload_release
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
with:
|
||||||
|
upload_url: ${{ github.event.release.upload_url }}
|
||||||
|
asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||||
|
asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
|
||||||
|
asset_content_type: application/zip
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
Push_Nuget_Package:
|
||||||
|
needs: Build_Project
|
||||||
|
runs-on: windows-2019
|
||||||
|
steps:
|
||||||
|
- name: Download Build Version Info
|
||||||
|
uses: actions/download-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Version
|
||||||
|
- name: Set Version Number
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Get-ChildItem "./Version"
|
||||||
|
$version = Get-Content -Path ./Version/version.txt
|
||||||
|
Write-Host "Version: $version"
|
||||||
|
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
Remove-Item -Path ./Version/version.txt
|
||||||
|
Remove-Item -Path ./Version
|
||||||
|
- name: Download Build output
|
||||||
|
uses: actions/download-artifact@v1
|
||||||
|
with:
|
||||||
|
name: Build
|
||||||
|
path: ./
|
||||||
|
- name: Unzip Build file
|
||||||
|
run: |
|
||||||
|
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||||
|
Remove-Item -Path .\*.zip
|
||||||
|
- name: Copy Files to root & delete output directory
|
||||||
|
run: |
|
||||||
|
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||||
|
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||||
|
Remove-Item -Path .\output -Recurse
|
||||||
|
- name: Add nuget.exe
|
||||||
|
uses: nuget/setup-nuget@v1
|
||||||
|
- name: Add Github Packages source
|
||||||
|
run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Add nuget.org API Key
|
||||||
|
run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
|
||||||
|
- name: Create nuget package
|
||||||
|
run: nuget pack "./PepperDash_Essentials_Core.nuspec" -version ${{ env.VERSION }}
|
||||||
|
- name: Publish nuget package to Github registry
|
||||||
|
run: nuget push **/*.nupkg -source github
|
||||||
|
- name: Publish nuget package to nuget.org
|
||||||
|
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -389,6 +389,3 @@ MigrationBackup/
|
|||||||
# Fody - auto-generated XML schema
|
# Fody - auto-generated XML schema
|
||||||
FodyWeavers.xsd
|
FodyWeavers.xsd
|
||||||
essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
|
essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
|
||||||
.DS_Store
|
|
||||||
/._PepperDash.Essentials.sln
|
|
||||||
.vscode/settings.json
|
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Essentials-Template-UI"]
|
||||||
|
path = Essentials-Template-UI
|
||||||
|
url = https://github.com/PepperDash/Essentials-Template-UI.git
|
||||||
|
|||||||
@@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -91,8 +91,8 @@ we receive and the availability of resources to evaluate contributions, we antic
|
|||||||
project remains dynamic and relevant. This may affect our responsiveness and ability to accept pull requests
|
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.
|
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.
|
- 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
|
There may be times when we recommend that you just share your code for some enhancement to Ghidra from your own
|
||||||
repository. As we identify and recognize extensions that are of general interest to Essentials, we
|
repository. As we identify and recognize extensions that are of general interest to the reverse engineering community, we
|
||||||
may seek to incorporate them with our baseline.
|
may seek to incorporate them with our baseline.
|
||||||
|
|
||||||
## Legal
|
## Legal
|
||||||
|
|||||||
1
Essentials-Template-UI
Submodule
1
Essentials-Template-UI
Submodule
Submodule Essentials-Template-UI added at 8eaf88791b
@@ -1,97 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
|
||||||
VisualStudioVersion = 17.4.33213.308
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials.Devices.Common", "src\PepperDash.Essentials.Devices.Common\PepperDash.Essentials.Devices.Common.csproj", "{53E204B7-97DD-441D-A96C-721DF014DF82}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90} = {E5336563-1194-501E-BC4A-79AD9283EF90}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials", "src\PepperDash.Essentials\PepperDash.Essentials.csproj", "{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90} = {E5336563-1194-501E-BC4A-79AD9283EF90}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials.Core", "src\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj", "{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90} = {E5336563-1194-501E-BC4A-79AD9283EF90}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mobile Control", "Mobile Control", "{B24989D7-32B5-48D5-9AE1-5F3B17D25206}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash.Essentials.MobileControl", "src\PepperDash.Essentials.MobileControl\PepperDash.Essentials.MobileControl.csproj", "{F6D362DE-2256-44B1-927A-8CE4705D839A}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90} = {E5336563-1194-501E-BC4A-79AD9283EF90}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash.Essentials.MobileControl.Messengers", "src\PepperDash.Essentials.MobileControl.Messengers\PepperDash.Essentials.MobileControl.Messengers.csproj", "{B438694F-8FF7-464A-9EC8-10427374471F}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90} = {E5336563-1194-501E-BC4A-79AD9283EF90}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Essentials", "Essentials", "{AD98B742-8D85-481C-A69D-D8D8ABED39EA}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash.Core", "src\PepperDash.Core\PepperDash.Core.csproj", "{E5336563-1194-501E-BC4A-79AD9283EF90}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug 4.7.2|Any CPU = Debug 4.7.2|Any CPU
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82}.Debug 4.7.2|Any CPU.ActiveCfg = Debug 4.7.2|Any CPU
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82}.Debug 4.7.2|Any CPU.Build.0 = Debug 4.7.2|Any CPU
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}.Debug 4.7.2|Any CPU.ActiveCfg = Debug 4.7.2|Any CPU
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}.Debug 4.7.2|Any CPU.Build.0 = Debug 4.7.2|Any CPU
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Debug 4.7.2|Any CPU.ActiveCfg = Debug 4.7.2|Any CPU
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Debug 4.7.2|Any CPU.Build.0 = Debug 4.7.2|Any CPU
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug 4.7.2|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug 4.7.2|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug 4.7.2|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug 4.7.2|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90}.Debug 4.7.2|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90}.Debug 4.7.2|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{53E204B7-97DD-441D-A96C-721DF014DF82} = {AD98B742-8D85-481C-A69D-D8D8ABED39EA}
|
|
||||||
{CB3B11BA-625C-4D35-B663-FDC5BE9A230E} = {AD98B742-8D85-481C-A69D-D8D8ABED39EA}
|
|
||||||
{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B} = {AD98B742-8D85-481C-A69D-D8D8ABED39EA}
|
|
||||||
{F6D362DE-2256-44B1-927A-8CE4705D839A} = {B24989D7-32B5-48D5-9AE1-5F3B17D25206}
|
|
||||||
{B438694F-8FF7-464A-9EC8-10427374471F} = {B24989D7-32B5-48D5-9AE1-5F3B17D25206}
|
|
||||||
{E5336563-1194-501E-BC4A-79AD9283EF90} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {6907A4BF-7201-47CF-AAB1-3597F3B8E1C3}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
49
PepperDashEssentials.sln
Normal file
49
PepperDashEssentials.sln
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDashEssentials", "PepperDashEssentials\PepperDashEssentials.csproj", "{1BED5BA9-88C4-4365-9362-6F4B128071D3}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{892B761C-E479-44CE-BD74-243E9214AF13} = {892B761C-E479-44CE-BD74-243E9214AF13}
|
||||||
|
{9199CE8A-0C9F-4952-8672-3EED798B284F} = {9199CE8A-0C9F-4952-8672-3EED798B284F}
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} = {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash_Essentials_Core", "essentials-framework\Essentials Core\PepperDashEssentialsBase\PepperDash_Essentials_Core.csproj", "{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Essentials Devices Common", "essentials-framework\Essentials Devices Common\Essentials Devices Common\Essentials Devices Common.csproj", "{892B761C-E479-44CE-BD74-243E9214AF13}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} = {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepperDash_Essentials_DM", "essentials-framework\Essentials DM\Essentials_DM\PepperDash_Essentials_DM.csproj", "{9199CE8A-0C9F-4952-8672-3EED798B284F}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} = {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1BED5BA9-88C4-4365-9362-6F4B128071D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1BED5BA9-88C4-4365-9362-6F4B128071D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1BED5BA9-88C4-4365-9362-6F4B128071D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1BED5BA9-88C4-4365-9362-6F4B128071D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{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
|
||||||
|
{892B761C-E479-44CE-BD74-243E9214AF13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{892B761C-E479-44CE-BD74-243E9214AF13}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{892B761C-E479-44CE-BD74-243E9214AF13}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{892B761C-E479-44CE-BD74-243E9214AF13}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{9199CE8A-0C9F-4952-8672-3EED798B284F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{9199CE8A-0C9F-4952-8672-3EED798B284F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{9199CE8A-0C9F-4952-8672-3EED798B284F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{9199CE8A-0C9F-4952-8672-3EED798B284F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -1,7 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using PepperDash.Essentials.Core;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.DSP;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -28,8 +39,6 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IBasicVolumeWithFeedback GetDevice()
|
public IBasicVolumeWithFeedback GetDevice()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("This method references DM CHASSIS Directly");
|
|
||||||
/*
|
|
||||||
// DM output card format: deviceKey--output~number, dm8x8-1--output~4
|
// DM output card format: deviceKey--output~number, dm8x8-1--output~4
|
||||||
var match = Regex.Match(DeviceKey, @"([-_\w]+)--(\w+)~(\d+)");
|
var match = Regex.Match(DeviceKey, @"([-_\w]+)--(\w+)~(\d+)");
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
@@ -84,8 +93,6 @@ namespace PepperDash.Essentials.Room.Config
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
* */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
PepperDashEssentials/Bridges/._EssentialsLightsBridge.cs
Normal file
BIN
PepperDashEssentials/Bridges/._EssentialsLightsBridge.cs
Normal file
Binary file not shown.
61
PepperDashEssentials/Bridges/AirMediaControllerBridge.cs
Normal file
61
PepperDashEssentials/Bridges/AirMediaControllerBridge.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
using PepperDash.Essentials.DM.AirMedia;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class AirMediaControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this AirMediaController airMedia, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
AirMediaControllerJoinMap joinMap = new AirMediaControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<AirMediaControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
Debug.Console(0, "Linking to Airmedia: {0}", airMedia.Name);
|
||||||
|
|
||||||
|
trilist.StringInput[joinMap.Name].StringValue = airMedia.Name;
|
||||||
|
|
||||||
|
var commMonitor = airMedia as ICommunicationMonitor;
|
||||||
|
if (commMonitor != null)
|
||||||
|
{
|
||||||
|
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
}
|
||||||
|
|
||||||
|
airMedia.IsInSessionFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsInSession]);
|
||||||
|
airMedia.HdmiVideoSyncDetectedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.HdmiVideoSync]);
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction(joinMap.AutomaticInputRoutingEnabled, new Action( airMedia.AirMedia.DisplayControl.EnableAutomaticRouting));
|
||||||
|
trilist.SetSigFalseAction(joinMap.AutomaticInputRoutingEnabled, new Action( airMedia.AirMedia.DisplayControl.DisableAutomaticRouting));
|
||||||
|
airMedia.AutomaticInputRoutingEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AutomaticInputRoutingEnabled]);
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.VideoOut, new Action<ushort>((u) => airMedia.SelectVideoOut(u)));
|
||||||
|
|
||||||
|
airMedia.VideoOutFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoOut]);
|
||||||
|
airMedia.ErrorFeedback.LinkInputSig(trilist.UShortInput[joinMap.ErrorFB]);
|
||||||
|
airMedia.NumberOfUsersConnectedFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfUsersConnectedFB]);
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.LoginCode, new Action<ushort>((u) => airMedia.AirMedia.AirMedia.LoginCode.UShortValue = u));
|
||||||
|
airMedia.LoginCodeFeedback.LinkInputSig(trilist.UShortInput[joinMap.LoginCode]);
|
||||||
|
|
||||||
|
airMedia.ConnectionAddressFeedback.LinkInputSig(trilist.StringInput[joinMap.ConnectionAddressFB]);
|
||||||
|
airMedia.HostnameFeedback.LinkInputSig(trilist.StringInput[joinMap.HostnameFB]);
|
||||||
|
airMedia.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumberFeedback]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
PepperDashEssentials/Bridges/AppleTvBridge.cs
Normal file
41
PepperDashEssentials/Bridges/AppleTvBridge.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class AppleTvApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this AppleTV appleTv, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
AppleTvJoinMap joinMap = new AppleTvJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<AppleTvJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
Debug.Console(0, "Linking to Bridge Type {0}", appleTv.GetType().Name.ToString());
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.UpArrow, (b) => appleTv.Up(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.DnArrow, (b) => appleTv.Down(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.LeftArrow, (b) => appleTv.Left(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.RightArrow, (b) => appleTv.Right(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Select, (b) => appleTv.Select(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Menu, (b) => appleTv.Menu(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.PlayPause, (b) => appleTv.Play(b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
PepperDashEssentials/Bridges/BridgeFactory.cs
Normal file
129
PepperDashEssentials/Bridges/BridgeFactory.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
using PepperDash.Essentials.Bridges;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Responsible for loading all of the device types for this library
|
||||||
|
/// </summary>
|
||||||
|
public class BridgeFactory
|
||||||
|
{
|
||||||
|
public BridgeFactory()
|
||||||
|
{
|
||||||
|
var eiscApiAdvancedFactory = new EiscApiAdvancedFactory() as IDeviceFactory;
|
||||||
|
eiscApiAdvancedFactory.LoadTypeFactories();
|
||||||
|
|
||||||
|
var eiscApiFactory = new EiscApiFactory() as IDeviceFactory;
|
||||||
|
eiscApiFactory.LoadTypeFactories();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CommBridge : Device
|
||||||
|
{
|
||||||
|
public CommBridgeProperties Properties { get; private set; }
|
||||||
|
|
||||||
|
public List<IBasicCommunication> CommDevices { get; private set; }
|
||||||
|
|
||||||
|
public CommBridge(string key, string name, JToken properties)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Properties = JsonConvert.DeserializeObject<CommBridgeProperties>(properties.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
// Create EiscApis
|
||||||
|
if (Properties.Eiscs != null)
|
||||||
|
{
|
||||||
|
foreach (var eisc in Properties.Eiscs)
|
||||||
|
{
|
||||||
|
var ApiEisc = new BridgeApiEisc(eisc.IpId, eisc.Hostname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var deviceKey in Properties.CommDevices)
|
||||||
|
{
|
||||||
|
var device = DeviceManager.GetDeviceForKey(deviceKey);
|
||||||
|
|
||||||
|
if (device != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "deviceKey {0} Found in Device Manager", device.Key);
|
||||||
|
CommDevices.Add(device as IBasicCommunication);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, "deviceKey {0} Not Found in Device Manager", deviceKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through all the CommDevices and link up their Actions and Feedbacks
|
||||||
|
|
||||||
|
Debug.Console(0, "Bridge {0} Activated", this.Name);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class EiscBridgeProperties
|
||||||
|
{
|
||||||
|
public string ParentDeviceKey { get; set; }
|
||||||
|
public eApiType ApiType { get; set; }
|
||||||
|
public List<EiscProperties> Eiscs { get; set; }
|
||||||
|
public string ApiOverrideFilePath { get; set; }
|
||||||
|
|
||||||
|
public class EiscProperties
|
||||||
|
{
|
||||||
|
public string IpId { get; set; }
|
||||||
|
public string Hostname { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CommBridgeProperties : EiscBridgeProperties
|
||||||
|
{
|
||||||
|
public List<string> CommDevices { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum eApiType { Eisc = 0 }
|
||||||
|
|
||||||
|
public class BridgeApiEisc
|
||||||
|
{
|
||||||
|
public uint Ipid { get; private set; }
|
||||||
|
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
|
||||||
|
|
||||||
|
public BridgeApiEisc(string ipid, string hostname)
|
||||||
|
{
|
||||||
|
Ipid = (UInt32)int.Parse(ipid, System.Globalization.NumberStyles.HexNumber);
|
||||||
|
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(Ipid, hostname, Global.ControlSystem);
|
||||||
|
Eisc.Register();
|
||||||
|
Eisc.SigChange += Eisc_SigChange;
|
||||||
|
Debug.Console(0, "BridgeApiEisc Created at Ipid {0}", ipid);
|
||||||
|
}
|
||||||
|
void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
||||||
|
{
|
||||||
|
if (Debug.Level >= 1)
|
||||||
|
Debug.Console(1, "BridgeApiEisc change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||||
|
var uo = args.Sig.UserObject;
|
||||||
|
if (uo is Action<bool>)
|
||||||
|
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||||
|
else if (uo is Action<ushort>)
|
||||||
|
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||||
|
else if (uo is Action<string>)
|
||||||
|
(uo as Action<string>)(args.Sig.StringValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
90
PepperDashEssentials/Bridges/Bridges.BridgeFactory.cs
Normal file
90
PepperDashEssentials/Bridges/Bridges.BridgeFactory.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using PepperDash.Essentials.Bridges;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials {
|
||||||
|
public class BridgeFactory {
|
||||||
|
public static IKeyed GetDevice(PepperDash.Essentials.Core.Config.DeviceConfig dc) {
|
||||||
|
// ? why is this static JTA 2018-06-13?
|
||||||
|
|
||||||
|
var key = dc.Key;
|
||||||
|
var name = dc.Name;
|
||||||
|
var type = dc.Type;
|
||||||
|
var properties = dc.Properties;
|
||||||
|
var propAnon = new { };
|
||||||
|
JsonConvert.DeserializeAnonymousType(dc.Properties.ToString(), propAnon);
|
||||||
|
|
||||||
|
var typeName = dc.Type.ToLower();
|
||||||
|
var groupName = dc.Group.ToLower();
|
||||||
|
|
||||||
|
Debug.Console(2, "Name {0}, Key {1}, Type {2}, Properties {3}", name, key, type, properties.ToString());
|
||||||
|
if (typeName == "essentialdm")
|
||||||
|
{
|
||||||
|
return new EssentialDM(key, name, properties);
|
||||||
|
}
|
||||||
|
else if (typeName == "essentialcomm")
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Launch Essential Comm");
|
||||||
|
return new EssentialComm(key, name, properties);
|
||||||
|
}
|
||||||
|
else if (typeName == "essentialdsp")
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Launch EssentialDsp");
|
||||||
|
return new EssentialDsp(key, name, properties);
|
||||||
|
}
|
||||||
|
else if (typeName == "essentialstvone")
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Launch essentialstvone");
|
||||||
|
return new EssentialsTVOne(key, name, properties);
|
||||||
|
}
|
||||||
|
else if (typeName == "essentialslighting")
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Launch essentialslighting");
|
||||||
|
return new EssentialsLightsBridge(key, name, properties);
|
||||||
|
}
|
||||||
|
else if (typeName == "eiscapi")
|
||||||
|
{
|
||||||
|
return new EiscApi(dc);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class BridgeApiEisc {
|
||||||
|
public uint Ipid;
|
||||||
|
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc;
|
||||||
|
public BridgeApiEisc(string ipid) {
|
||||||
|
Ipid = (UInt32)int.Parse(ipid, System.Globalization.NumberStyles.HexNumber);
|
||||||
|
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(Ipid, "127.0.0.2", Global.ControlSystem);
|
||||||
|
Eisc.Register();
|
||||||
|
Eisc.SigChange += Eisc_SigChange;
|
||||||
|
Debug.Console(2, "BridgeApiEisc Created at Ipid {0}", ipid);
|
||||||
|
}
|
||||||
|
void Eisc_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args) {
|
||||||
|
if (Debug.Level >= 1)
|
||||||
|
Debug.Console(2, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||||
|
var uo = args.Sig.UserObject;
|
||||||
|
if (uo is Action<bool>)
|
||||||
|
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||||
|
else if (uo is Action<ushort>)
|
||||||
|
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||||
|
else if (uo is Action<string>)
|
||||||
|
(uo as Action<string>)(args.Sig.StringValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
38
PepperDashEssentials/Bridges/C2nRthsControllerBridge.cs
Normal file
38
PepperDashEssentials/Bridges/C2nRthsControllerBridge.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class C2nRthsControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this C2nRthsController device, BasicTriList triList, uint joinStart,
|
||||||
|
string joinMapKey)
|
||||||
|
{
|
||||||
|
var joinMap = new C2nRthsControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<C2nRthsControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, device, "Linking to Trilist '{0}'", triList.ID.ToString("X"));
|
||||||
|
|
||||||
|
|
||||||
|
triList.SetBoolSigAction(joinMap.TemperatureFormat, device.SetTemperatureFormat);
|
||||||
|
|
||||||
|
device.IsOnline.LinkInputSig(triList.BooleanInput[joinMap.IsOnline]);
|
||||||
|
device.TemperatureFeedback.LinkInputSig(triList.UShortInput[joinMap.Temperature]);
|
||||||
|
device.HumidityFeedback.LinkInputSig(triList.UShortInput[joinMap.Humidity]);
|
||||||
|
|
||||||
|
triList.StringInput[joinMap.Name].StringValue = device.Name;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
169
PepperDashEssentials/Bridges/CameraControllerBridge.cs
Normal file
169
PepperDashEssentials/Bridges/CameraControllerBridge.cs
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class CameraControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this PepperDash.Essentials.Devices.Common.Cameras.CameraBase cameraDevice, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApi bridge)
|
||||||
|
{
|
||||||
|
CameraControllerJoinMap joinMap = new CameraControllerJoinMap(joinStart);
|
||||||
|
|
||||||
|
// Adds the join map to the bridge
|
||||||
|
bridge.AddJoinMap(cameraDevice.Key, joinMap);
|
||||||
|
|
||||||
|
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (customJoins != null)
|
||||||
|
{
|
||||||
|
joinMap.SetCustomJoinData(customJoins);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
Debug.Console(0, "Linking to Bridge Type {0}", cameraDevice.GetType().Name.ToString());
|
||||||
|
|
||||||
|
var commMonitor = cameraDevice as ICommunicationMonitor;
|
||||||
|
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||||
|
|
||||||
|
var ptzCamera = cameraDevice as IHasCameraPtzControl;
|
||||||
|
|
||||||
|
if (ptzCamera != null)
|
||||||
|
{
|
||||||
|
trilist.SetBoolSigAction(joinMap.PanLeft.JoinNumber, (b) =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
ptzCamera.PanLeft();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptzCamera.PanStop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
trilist.SetBoolSigAction(joinMap.PanRight.JoinNumber, (b) =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
ptzCamera.PanRight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptzCamera.PanStop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.TiltUp.JoinNumber, (b) =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
ptzCamera.TiltUp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptzCamera.TiltStop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
trilist.SetBoolSigAction(joinMap.TiltDown.JoinNumber, (b) =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
ptzCamera.TiltDown();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptzCamera.TiltStop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.ZoomIn.JoinNumber, (b) =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
ptzCamera.ZoomIn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptzCamera.ZoomStop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.ZoomOut.JoinNumber, (b) =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
ptzCamera.ZoomOut();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptzCamera.ZoomStop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraDevice is IPower)
|
||||||
|
{
|
||||||
|
var powerCamera = cameraDevice as IPower;
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () => powerCamera.PowerOn());
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () => powerCamera.PowerOff());
|
||||||
|
|
||||||
|
powerCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||||
|
powerCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraDevice is ICommunicationMonitor)
|
||||||
|
{
|
||||||
|
var monitoredCamera = cameraDevice as ICommunicationMonitor;
|
||||||
|
monitoredCamera.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cameraDevice is IHasCameraPresets)
|
||||||
|
{
|
||||||
|
// Set the preset lables when they change
|
||||||
|
var presetsCamera = cameraDevice as IHasCameraPresets;
|
||||||
|
presetsCamera.PresetsListHasChanged += new EventHandler<EventArgs>((o, a) =>
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= joinMap.NumberOfPresets.JoinNumber; i++)
|
||||||
|
{
|
||||||
|
int tempNum = i - 1;
|
||||||
|
|
||||||
|
string label = "" ;
|
||||||
|
|
||||||
|
var preset = presetsCamera.Presets.FirstOrDefault(p => p.ID.Equals(i));
|
||||||
|
|
||||||
|
if (preset != null)
|
||||||
|
label = preset.Description;
|
||||||
|
|
||||||
|
trilist.SetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum), label);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < joinMap.NumberOfPresets.JoinNumber; i++)
|
||||||
|
{
|
||||||
|
int tempNum = i;
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction((ushort)(joinMap.PresetRecallStart.JoinNumber + tempNum), () =>
|
||||||
|
{
|
||||||
|
presetsCamera.PresetSelect(tempNum);
|
||||||
|
});
|
||||||
|
trilist.SetSigTrueAction((ushort)(joinMap.PresetSaveStart.JoinNumber + tempNum), () =>
|
||||||
|
{
|
||||||
|
var label = trilist.GetString((ushort)(joinMap.PresetLabelStart.JoinNumber + tempNum));
|
||||||
|
|
||||||
|
presetsCamera.PresetStore(tempNum, label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
288
PepperDashEssentials/Bridges/DmChassisControllerBridge.cs
Normal file
288
PepperDashEssentials/Bridges/DmChassisControllerBridge.cs
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class DmChassisControllerApiExtentions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this DmChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
DmChassisControllerJoinMap joinMap = new DmChassisControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<DmChassisControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, dmChassis, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
var chassis = dmChassis.Chassis as DmMDMnxn;
|
||||||
|
|
||||||
|
dmChassis.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.SystemId, new Action<ushort>(o => chassis.SystemId.UShortValue = o));
|
||||||
|
trilist.SetSigTrueAction(joinMap.SystemId, new Action(() => chassis.ApplySystemId()));
|
||||||
|
|
||||||
|
dmChassis.SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId]);
|
||||||
|
dmChassis.SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId]);
|
||||||
|
|
||||||
|
// Link up outputs
|
||||||
|
for (uint i = 1; i <= dmChassis.Chassis.NumberOfOutputs; i++)
|
||||||
|
{
|
||||||
|
var ioSlot = i;
|
||||||
|
|
||||||
|
// Control
|
||||||
|
trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action<ushort>(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)));
|
||||||
|
trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, new Action<ushort>(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)));
|
||||||
|
trilist.SetUShortSigAction(joinMap.OutputUsb + ioSlot, new Action<ushort>(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput)));
|
||||||
|
trilist.SetUShortSigAction(joinMap.InputUsb + ioSlot, new Action<ushort>(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput)));
|
||||||
|
|
||||||
|
if (dmChassis.TxDictionary.ContainsKey(ioSlot))
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot);
|
||||||
|
var txKey = dmChassis.TxDictionary[ioSlot];
|
||||||
|
var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase;
|
||||||
|
|
||||||
|
var advancedTxDevice = basicTxDevice as DmTxControllerBase;
|
||||||
|
|
||||||
|
if (dmChassis.Chassis is DmMd8x8Cpu3 || dmChassis.Chassis is DmMd8x8Cpu3rps
|
||||||
|
|| dmChassis.Chassis is DmMd16x16Cpu3 || dmChassis.Chassis is DmMd16x16Cpu3rps
|
||||||
|
|| dmChassis.Chassis is DmMd32x32Cpu3 || dmChassis.Chassis is DmMd32x32Cpu3rps)
|
||||||
|
{
|
||||||
|
dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (advancedTxDevice != null)
|
||||||
|
{
|
||||||
|
advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
|
||||||
|
Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot);
|
||||||
|
}
|
||||||
|
else if (dmChassis.InputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot);
|
||||||
|
dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basicTxDevice != null && advancedTxDevice == null)
|
||||||
|
trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true;
|
||||||
|
|
||||||
|
if (advancedTxDevice != null)
|
||||||
|
{
|
||||||
|
advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
|
||||||
|
}
|
||||||
|
else if(advancedTxDevice == null || basicTxDevice != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot);
|
||||||
|
dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
|
||||||
|
|
||||||
|
var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)];
|
||||||
|
if (inputPort != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Port value for input card {0} is set", ioSlot);
|
||||||
|
var port = inputPort.Port;
|
||||||
|
|
||||||
|
if (port != null)
|
||||||
|
{
|
||||||
|
if (port is HdmiInputWithCEC)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Port is HdmiInputWithCec");
|
||||||
|
|
||||||
|
var hdmiInPortWCec = port as HdmiInputWithCEC;
|
||||||
|
|
||||||
|
if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown)
|
||||||
|
{
|
||||||
|
SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist);
|
||||||
|
}
|
||||||
|
|
||||||
|
dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]);
|
||||||
|
|
||||||
|
if(dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot))
|
||||||
|
trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot];
|
||||||
|
else
|
||||||
|
trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)];
|
||||||
|
|
||||||
|
if(inputPort != null)
|
||||||
|
{
|
||||||
|
var port = inputPort.Port;
|
||||||
|
|
||||||
|
if (port is DMInputPortWithCec)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Port is DMInputPortWithCec");
|
||||||
|
|
||||||
|
var dmInPortWCec = port as DMInputPortWithCec;
|
||||||
|
|
||||||
|
if (dmInPortWCec != null)
|
||||||
|
{
|
||||||
|
SetHdcpStateAction(dmChassis.PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist);
|
||||||
|
}
|
||||||
|
|
||||||
|
dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]);
|
||||||
|
|
||||||
|
if (dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot))
|
||||||
|
trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot];
|
||||||
|
else
|
||||||
|
trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
|
||||||
|
|
||||||
|
var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)];
|
||||||
|
if (inputPort != null)
|
||||||
|
{
|
||||||
|
var hdmiPort = inputPort.Port as EndpointHdmiInput;
|
||||||
|
|
||||||
|
if (hdmiPort != null)
|
||||||
|
{
|
||||||
|
SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState + ioSlot, trilist);
|
||||||
|
dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmChassis.RxDictionary.ContainsKey(ioSlot))
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot);
|
||||||
|
var rxKey = dmChassis.RxDictionary[ioSlot];
|
||||||
|
var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase;
|
||||||
|
var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase;
|
||||||
|
if (dmChassis.Chassis is DmMd8x8Cpu3 || dmChassis.Chassis is DmMd8x8Cpu3rps
|
||||||
|
|| dmChassis.Chassis is DmMd16x16Cpu3 || dmChassis.Chassis is DmMd16x16Cpu3rps
|
||||||
|
|| dmChassis.Chassis is DmMd32x32Cpu3 || dmChassis.Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null)
|
||||||
|
{
|
||||||
|
dmChassis.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]);
|
||||||
|
}
|
||||||
|
else if (rxDevice != null)
|
||||||
|
{
|
||||||
|
rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feedback
|
||||||
|
dmChassis.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]);
|
||||||
|
dmChassis.AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]);
|
||||||
|
dmChassis.UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb + ioSlot]);
|
||||||
|
dmChassis.UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb + ioSlot]);
|
||||||
|
|
||||||
|
dmChassis.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]);
|
||||||
|
dmChassis.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]);
|
||||||
|
dmChassis.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]);
|
||||||
|
dmChassis.OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]);
|
||||||
|
|
||||||
|
dmChassis.OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputDisabledByHdcp + ioSlot]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist)
|
||||||
|
{
|
||||||
|
if (hdcpTypeSimple)
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(s =>
|
||||||
|
{
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOff();
|
||||||
|
}
|
||||||
|
else if (s > 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOn();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(u =>
|
||||||
|
{
|
||||||
|
port.HdcpReceiveCapability = (eHdcpCapabilityType)u;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)
|
||||||
|
{
|
||||||
|
if (hdcpTypeSimple)
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(s =>
|
||||||
|
{
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOff();
|
||||||
|
}
|
||||||
|
else if (s > 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOn();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(u =>
|
||||||
|
{
|
||||||
|
port.HdcpCapability = (eHdcpCapabilityType)u;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist)
|
||||||
|
{
|
||||||
|
if (!supportsHdcp2)
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(s =>
|
||||||
|
{
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOff();
|
||||||
|
}
|
||||||
|
else if (s > 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOn();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(u =>
|
||||||
|
{
|
||||||
|
port.HdcpReceiveCapability = (eHdcpCapabilityType)u;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
44
PepperDashEssentials/Bridges/DmRmcControllerBridge.cs
Normal file
44
PepperDashEssentials/Bridges/DmRmcControllerBridge.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class DmRmcControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
DmRmcControllerJoinMap joinMap = new DmRmcControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<DmRmcControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
if(rmc.VideoOutputResolutionFeedback != null)
|
||||||
|
rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution]);
|
||||||
|
if(rmc.EdidManufacturerFeedback != null)
|
||||||
|
rmc.EdidManufacturerFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidManufacturer]);
|
||||||
|
if(rmc.EdidNameFeedback != null)
|
||||||
|
rmc.EdidNameFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidName]);
|
||||||
|
if(rmc.EdidPreferredTimingFeedback != null)
|
||||||
|
rmc.EdidPreferredTimingFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidPrefferedTiming]);
|
||||||
|
if(rmc.EdidSerialNumberFeedback != null)
|
||||||
|
rmc.EdidSerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidSerialNumber]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
153
PepperDashEssentials/Bridges/DmTxControllerBridge.cs
Normal file
153
PepperDashEssentials/Bridges/DmTxControllerBridge.cs
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class DmTxControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this DmTxControllerBase tx, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
DmTxControllerJoinMap joinMap = new DmTxControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<DmTxControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus]);
|
||||||
|
tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution]);
|
||||||
|
trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability;
|
||||||
|
|
||||||
|
bool hdcpTypeSimple;
|
||||||
|
|
||||||
|
if (tx.Hardware is DmTx4kX02CBase || tx.Hardware is DmTx4kzX02CBase)
|
||||||
|
hdcpTypeSimple = false;
|
||||||
|
else
|
||||||
|
hdcpTypeSimple = true;
|
||||||
|
|
||||||
|
if (tx is ITxRouting)
|
||||||
|
{
|
||||||
|
var txR = tx as ITxRouting;
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.VideoInput,
|
||||||
|
new Action<ushort>(i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Video)));
|
||||||
|
trilist.SetUShortSigAction(joinMap.AudioInput,
|
||||||
|
new Action<ushort>(i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Audio)));
|
||||||
|
|
||||||
|
txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput]);
|
||||||
|
txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput]);
|
||||||
|
|
||||||
|
trilist.UShortInput[joinMap.HdcpSupportCapability].UShortValue = (ushort)tx.HdcpSupportCapability;
|
||||||
|
|
||||||
|
if (txR.InputPorts[DmPortName.HdmiIn] != null)
|
||||||
|
{
|
||||||
|
var inputPort = txR.InputPorts[DmPortName.HdmiIn];
|
||||||
|
|
||||||
|
if (tx.Feedbacks["HdmiInHdcpCapability"] != null)
|
||||||
|
(tx.Feedbacks["HdmiInHdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
|
||||||
|
|
||||||
|
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||||
|
{
|
||||||
|
var port = inputPort.Port as EndpointHdmiInput;
|
||||||
|
|
||||||
|
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txR.InputPorts[DmPortName.HdmiIn1] != null)
|
||||||
|
{
|
||||||
|
var inputPort = txR.InputPorts[DmPortName.HdmiIn1];
|
||||||
|
|
||||||
|
if (tx.Feedbacks["HdmiIn1HdcpCapability"] != null)
|
||||||
|
(tx.Feedbacks["HdmiIn1HdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
|
||||||
|
|
||||||
|
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||||
|
{
|
||||||
|
var port = inputPort.Port as EndpointHdmiInput;
|
||||||
|
|
||||||
|
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState, trilist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txR.InputPorts[DmPortName.HdmiIn2] != null)
|
||||||
|
{
|
||||||
|
var inputPort = txR.InputPorts[DmPortName.HdmiIn2];
|
||||||
|
|
||||||
|
if (tx.Feedbacks["HdmiIn2HdcpCapability"] != null)
|
||||||
|
(tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback).LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState]);
|
||||||
|
|
||||||
|
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||||
|
{
|
||||||
|
var port = inputPort.Port as EndpointHdmiInput;
|
||||||
|
|
||||||
|
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port2HdcpState, trilist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var txFreeRun = tx as IHasFreeRun;
|
||||||
|
if (txFreeRun != null)
|
||||||
|
{
|
||||||
|
txFreeRun.FreeRunEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FreeRunEnabled]);
|
||||||
|
trilist.SetBoolSigAction(joinMap.FreeRunEnabled, new Action<bool>(b => txFreeRun.SetFreeRunEnabled(b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
var txVga = tx as IVgaBrightnessContrastControls;
|
||||||
|
{
|
||||||
|
txVga.VgaBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaBrightness]);
|
||||||
|
txVga.VgaContrastFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaContrast]);
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.VgaBrightness, new Action<ushort>(u => txVga.SetVgaBrightness(u)));
|
||||||
|
trilist.SetUShortSigAction(joinMap.VgaContrast, new Action<ushort>(u => txVga.SetVgaContrast(u)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)
|
||||||
|
{
|
||||||
|
if (hdcpTypeSimple)
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(s =>
|
||||||
|
{
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOff();
|
||||||
|
}
|
||||||
|
else if (s > 0)
|
||||||
|
{
|
||||||
|
port.HdcpSupportOn();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trilist.SetUShortSigAction(join,
|
||||||
|
new Action<ushort>(s =>
|
||||||
|
{
|
||||||
|
port.HdcpCapability = (eHdcpCapabilityType)s;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class DmpsAudioOutputControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this DmpsAudioOutputController dmAudioOutputController, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
DmpsAudioOutputControllerJoinMap joinMap = new DmpsAudioOutputControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<DmpsAudioOutputControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, dmAudioOutputController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
if (dmAudioOutputController.MasterVolumeLevel != null)
|
||||||
|
{
|
||||||
|
SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.MasterVolumeLevel, joinMap.MasterVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmAudioOutputController.SourceVolumeLevel != null)
|
||||||
|
{
|
||||||
|
SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.SourceVolumeLevel, joinMap.SourceVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmAudioOutputController.Codec1VolumeLevel != null)
|
||||||
|
{
|
||||||
|
SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.Codec1VolumeLevel, joinMap.Codec1Volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dmAudioOutputController.Codec2VolumeLevel != null)
|
||||||
|
{
|
||||||
|
SetUpDmpsAudioOutputJoins(trilist, dmAudioOutputController.Codec2VolumeLevel, joinMap.Codec2Volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetUpDmpsAudioOutputJoins(BasicTriList trilist, DmpsAudioOutput output, uint joinStart)
|
||||||
|
{
|
||||||
|
var volumeLevelJoin = joinStart;
|
||||||
|
var muteOnJoin = joinStart;
|
||||||
|
var muteOffJoin = joinStart + 1;
|
||||||
|
var volumeUpJoin = joinStart + 2;
|
||||||
|
var volumeDownJoin = joinStart + 3;
|
||||||
|
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(volumeLevelJoin, new Action<ushort>(o => output.SetVolume(o)));
|
||||||
|
output.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[volumeLevelJoin]);
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction(muteOnJoin, new Action(output.MuteOn));
|
||||||
|
output.MuteFeedback.LinkInputSig(trilist.BooleanInput[muteOnJoin]);
|
||||||
|
trilist.SetSigTrueAction(muteOffJoin, new Action(output.MuteOff));
|
||||||
|
output.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[muteOffJoin]);
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(volumeUpJoin, new Action<bool>(b => output.VolumeUp(b)));
|
||||||
|
trilist.SetBoolSigAction(volumeDownJoin, new Action<bool>(b => output.VolumeDown(b)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
128
PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs
Normal file
128
PepperDashEssentials/Bridges/DmpsRoutingControllerBridge.cs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class DmpsRoutingControllerApiExtentions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this DmpsRoutingController dmpsRouter, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
DmpsRoutingControllerJoinMap joinMap = new DmpsRoutingControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<DmpsRoutingControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, dmpsRouter, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
// Link up outputs
|
||||||
|
for (uint i = 1; i <= dmpsRouter.Dmps.NumberOfSwitcherInputs; i++)
|
||||||
|
{
|
||||||
|
Debug.Console(2, dmpsRouter, "Linking Input Card {0}", i);
|
||||||
|
|
||||||
|
var ioSlot = i;
|
||||||
|
|
||||||
|
//if (dmpsRouter.TxDictionary.ContainsKey(ioSlot))
|
||||||
|
//{
|
||||||
|
// Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot);
|
||||||
|
// var TxKey = dmpsRouter.TxDictionary[ioSlot];
|
||||||
|
// var TxDevice = DeviceManager.GetDeviceForKey(TxKey) as DmTxControllerBase;
|
||||||
|
// //TxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
|
||||||
|
// // TxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
|
||||||
|
// // trilist.SetUShortSigAction((ApiMap.HdcpSupport[ioSlot]), u => TxDevice.SetHdcpSupportAll((ePdtHdcpSupport)(u)));
|
||||||
|
// // TxDevice.HdcpSupportAllFeedback.LinkInputSig(trilist.UShortInput[joinMap. + ioSlot]);
|
||||||
|
// // trilist.UShortInput[ApiMap.HdcpSupportCapability[ioSlot]].UShortValue = TxDevice.HdcpSupportCapability;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// // dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[ApiMap.TxVideoSyncStatus[ioSlot]]);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if(dmpsRouter.VideoInputSyncFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]);
|
||||||
|
|
||||||
|
if (dmpsRouter.InputNameFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]);
|
||||||
|
|
||||||
|
trilist.SetStringSigAction(joinMap.InputNames + ioSlot, new Action<string>(s =>
|
||||||
|
{
|
||||||
|
var inputCard = dmpsRouter.Dmps.SwitcherInputs[ioSlot] as DMInput;
|
||||||
|
|
||||||
|
if (inputCard != null)
|
||||||
|
{
|
||||||
|
if (inputCard.NameFeedback != null && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue) && inputCard.NameFeedback.StringValue != s)
|
||||||
|
if(inputCard.Name != null)
|
||||||
|
inputCard.Name.StringValue = s;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
if(dmpsRouter.InputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i = 1; i <= dmpsRouter.Dmps.NumberOfSwitcherOutputs; i++)
|
||||||
|
{
|
||||||
|
Debug.Console(2, dmpsRouter, "Linking Output Card {0}", i);
|
||||||
|
|
||||||
|
var ioSlot = i;
|
||||||
|
// Control
|
||||||
|
trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action<ushort>(o => dmpsRouter.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)));
|
||||||
|
trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, new Action<ushort>(o => dmpsRouter.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)));
|
||||||
|
|
||||||
|
trilist.SetStringSigAction(joinMap.OutputNames + ioSlot, new Action<string>(s =>
|
||||||
|
{
|
||||||
|
var outputCard = dmpsRouter.Dmps.SwitcherOutputs[ioSlot] as DMOutput;
|
||||||
|
|
||||||
|
//Debug.Console(2, dmpsRouter, "Output Name String Sig Action for Output Card {0}", ioSlot);
|
||||||
|
|
||||||
|
if (outputCard != null)
|
||||||
|
{
|
||||||
|
//Debug.Console(2, dmpsRouter, "Card Type: {0}", outputCard.CardInputOutputType);
|
||||||
|
|
||||||
|
if (!(outputCard is Crestron.SimplSharpPro.DM.Cards.Card.Dmps3CodecOutput) && outputCard.NameFeedback != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
|
||||||
|
{
|
||||||
|
//Debug.Console(2, dmpsRouter, "NameFeedabck: {0}", outputCard.NameFeedback.StringValue);
|
||||||
|
|
||||||
|
if (outputCard.NameFeedback.StringValue != s && outputCard.Name != null)
|
||||||
|
{
|
||||||
|
outputCard.Name.StringValue = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Feedback
|
||||||
|
if(dmpsRouter.VideoOutputFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]);
|
||||||
|
if (dmpsRouter.AudioOutputFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]);
|
||||||
|
if (dmpsRouter.OutputNameFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]);
|
||||||
|
if (dmpsRouter.OutputVideoRouteNameFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]);
|
||||||
|
if (dmpsRouter.OutputAudioRouteNameFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]);
|
||||||
|
if (dmpsRouter.OutputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||||
|
dmpsRouter.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
PepperDashEssentials/Bridges/DspControllerBridge.cs
Normal file
120
PepperDashEssentials/Bridges/DspControllerBridge.cs
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
public static class SamsungDisplayControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this PepperDash.Essentials.Core.TwoWayDisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
var joinMap = JoinMapHelper.GetJoinMapForDevice(joinMapKey) as DisplayControllerJoinMap;
|
||||||
|
|
||||||
|
if (joinMap == null)
|
||||||
|
{
|
||||||
|
joinMap = new DisplayControllerJoinMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
Debug.Console(0, "Linking to lighting Type {0}", displayDevice.GetType().Name.ToString());
|
||||||
|
|
||||||
|
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||||
|
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
|
||||||
|
|
||||||
|
// Poewer Off
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOff, () => displayDevice.PowerOff());
|
||||||
|
displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff]);
|
||||||
|
|
||||||
|
// Poewer On
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOn, () => displayDevice.PowerOn());
|
||||||
|
displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn]);
|
||||||
|
|
||||||
|
// GenericLighitng Actions & FeedBack
|
||||||
|
|
||||||
|
// int sceneIndex = 1;
|
||||||
|
/*
|
||||||
|
foreach (var scene in displayDevice.LightingScenes)
|
||||||
|
{
|
||||||
|
var tempIndex = sceneIndex - 1;
|
||||||
|
//trilist.SetSigTrueAction((uint)(joinMap.LightingSceneOffset + sceneIndex), () => displayDevice.SelectScene(displayDevice.LightingScenes[tempIndex]));
|
||||||
|
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)]);
|
||||||
|
trilist.StringInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)].StringValue = scene.Name;
|
||||||
|
trilist.BooleanInput[(uint)(joinMap.ButtonVisibilityOffset + sceneIndex)].BoolValue = true;
|
||||||
|
sceneIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayDevice.GetType().Name.ToString() == "LutronQuantumArea")
|
||||||
|
{
|
||||||
|
var lutronDevice = displayDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
|
||||||
|
lutronDevice.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
trilist.SetStringSigAction(joinMap.IntegrationIdSet, s => lutronDevice.IntegrationId = s);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//ApiEisc.Eisc.SetStringSigAction(ApiMap.integrationID, (s) => { lutronLights.IntegrationId = s; });
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
var lutronLights = displayDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
|
||||||
|
|
||||||
|
|
||||||
|
for (uint i = 1; i <= lightingBase.CircuitCount; i++)
|
||||||
|
{
|
||||||
|
var circuit = i;
|
||||||
|
lightingBase.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]);
|
||||||
|
lightingBase.CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]);
|
||||||
|
lightingBase.CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]);
|
||||||
|
trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => lightingBase.CycleCircuit(circuit - 1));
|
||||||
|
trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => lightingBase.TurnOnCircuit(circuit - 1));
|
||||||
|
trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => lightingBase.TurnOffCircuit(circuit - 1));
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class DisplayControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
public uint PowerOff { get; set; }
|
||||||
|
public uint PowerOn { get; set; }
|
||||||
|
public uint SelectScene { get; set; }
|
||||||
|
public uint LightingSceneOffset { get; set; }
|
||||||
|
public uint ButtonVisibilityOffset { get; set; }
|
||||||
|
public uint IntegrationIdSet { get; set; }
|
||||||
|
|
||||||
|
public DisplayControllerJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 1;
|
||||||
|
PowerOff = 1;
|
||||||
|
PowerOn = 2;
|
||||||
|
SelectScene = 1;
|
||||||
|
IntegrationIdSet = 1;
|
||||||
|
LightingSceneOffset = 10;
|
||||||
|
ButtonVisibilityOffset = 40;
|
||||||
|
// Analog
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
PowerOff = PowerOff + joinOffset;
|
||||||
|
PowerOn = PowerOn + joinOffset;
|
||||||
|
SelectScene = SelectScene + joinOffset;
|
||||||
|
LightingSceneOffset = LightingSceneOffset + joinOffset;
|
||||||
|
ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
196
PepperDashEssentials/Bridges/EiscBridge.cs
Normal file
196
PepperDashEssentials/Bridges/EiscBridge.cs
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use 'eiscapiadvanced' in configurations going forward")]
|
||||||
|
public class EiscApi : BridgeApi
|
||||||
|
{
|
||||||
|
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
|
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
|
||||||
|
|
||||||
|
public EiscApi(DeviceConfig dc) :
|
||||||
|
base(dc.Key)
|
||||||
|
{
|
||||||
|
PropertiesConfig = dc.Properties.ToObject<EiscApiPropertiesConfig>();
|
||||||
|
//PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
|
||||||
|
|
||||||
|
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem);
|
||||||
|
|
||||||
|
Eisc.SigChange += Eisc_SigChange;
|
||||||
|
|
||||||
|
AddPostActivationAction(() =>
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Linking Devices...");
|
||||||
|
|
||||||
|
foreach (var d in PropertiesConfig.Devices)
|
||||||
|
{
|
||||||
|
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||||
|
|
||||||
|
if (device == null) continue;
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||||
|
if (typeof(IBridge).IsAssignableFrom(device.GetType().GetCType())) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type.
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "'{0}' is IBridge", device.Key);
|
||||||
|
|
||||||
|
var dev = device as IBridge;
|
||||||
|
|
||||||
|
if (dev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Cast to IBridge failed for {0}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
|
||||||
|
}
|
||||||
|
if (!typeof(IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType())) continue;
|
||||||
|
Debug.Console(2, this, "'{0}' is IBridgeAdvanced", device.Key);
|
||||||
|
|
||||||
|
var advDev = device as IBridgeAdvanced;
|
||||||
|
|
||||||
|
if (advDev == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Cast to IBridgeAdvanced failed for {0}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
advDev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, null);
|
||||||
|
}
|
||||||
|
catch (NullReferenceException)
|
||||||
|
{
|
||||||
|
Debug.ConsoleWithLog(0, this,
|
||||||
|
"Please update the bridge config to use EiscBridgeAdvanced with this device: {0}", device.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.Console(1, this, "Devices Linked.");
|
||||||
|
|
||||||
|
var registerResult = Eisc.Register();
|
||||||
|
|
||||||
|
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Registration result: {0}", registerResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used for debugging to trigger an action based on a join number and type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="join"></param>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="state"></param>
|
||||||
|
public void ExecuteJoinAction(uint join, string type, object state)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (type.ToLower())
|
||||||
|
{
|
||||||
|
case "digital":
|
||||||
|
{
|
||||||
|
var uo = Eisc.BooleanOutput[join].UserObject as Action<bool>;
|
||||||
|
if (uo != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Executing Action: {0}", uo.ToString());
|
||||||
|
uo(Convert.ToBoolean(state));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(1, this, "User Action is null. Nothing to Execute");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "analog":
|
||||||
|
{
|
||||||
|
var uo = Eisc.BooleanOutput[join].UserObject as Action<ushort>;
|
||||||
|
if (uo != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Executing Action: {0}", uo.ToString());
|
||||||
|
uo(Convert.ToUInt16(state));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(1, this, "User Action is null. Nothing to Execute"); break;
|
||||||
|
}
|
||||||
|
case "serial":
|
||||||
|
{
|
||||||
|
var uo = Eisc.BooleanOutput[join].UserObject as Action<string>;
|
||||||
|
if (uo != null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Executing Action: {0}", uo.ToString());
|
||||||
|
uo(Convert.ToString(state));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(1, this, "User Action is null. Nothing to Execute");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Unknown join type. Use digital/serial/analog");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles incoming sig changes
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentDevice"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Debug.Level >= 1)
|
||||||
|
Debug.Console(2, this, "EiscApi change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||||
|
var uo = args.Sig.UserObject;
|
||||||
|
|
||||||
|
if (uo == null) return;
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Executing Action: {0}", uo.ToString());
|
||||||
|
if (uo is Action<bool>)
|
||||||
|
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||||
|
else if (uo is Action<ushort>)
|
||||||
|
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||||
|
else if (uo is Action<string>)
|
||||||
|
(uo as Action<string>)(args.Sig.StringValue);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EiscApiFactory : EssentialsDeviceFactory<EiscApiAdvanced>
|
||||||
|
{
|
||||||
|
public EiscApiFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "eiscapi" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Factory Attempting to create new EiscApi Device");
|
||||||
|
|
||||||
|
return new EiscApi(dc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
144
PepperDashEssentials/Bridges/EssentialComms.cs
Normal file
144
PepperDashEssentials/Bridges/EssentialComms.cs
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.CrestronThread;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials {
|
||||||
|
public class EssentialCommConfig {
|
||||||
|
public string[] EiscApiIpids;
|
||||||
|
public EssentialCommCommConnectionConfigs[] CommConnections;
|
||||||
|
}
|
||||||
|
public class EssentialCommCommConnectionConfigs {
|
||||||
|
public uint joinNumber {get; set; }
|
||||||
|
public EssentialsControlPropertiesConfig control { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EssentialCommsPort {
|
||||||
|
public IBasicCommunication Comm;
|
||||||
|
public IntFeedback StatusFeedback;
|
||||||
|
public BoolFeedback ConnectedFeedback;
|
||||||
|
public List<EssentialComApiMap> Outputs = new List<EssentialComApiMap>();
|
||||||
|
public String RxBuffer;
|
||||||
|
public EssentialCommsPort(EssentialsControlPropertiesConfig config, string keyPrefix) {
|
||||||
|
Comm = CommFactory.CreateCommForConfig(config, keyPrefix);
|
||||||
|
// var PortGather = new CommunicationGather(Comm, config.EndOfLineChar);
|
||||||
|
Comm.TextReceived += new EventHandler<GenericCommMethodReceiveTextArgs>(Communication_TextReceived);
|
||||||
|
|
||||||
|
var socket = Comm as ISocketStatus;
|
||||||
|
StatusFeedback = new IntFeedback(() => { return (int)socket.ClientStatus; });
|
||||||
|
ConnectedFeedback = new BoolFeedback(() => { return Comm.IsConnected; });
|
||||||
|
|
||||||
|
if (socket != null) {
|
||||||
|
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void socket_ConnectionChange(object sender, GenericSocketStatusChageEventArgs e) {
|
||||||
|
StatusFeedback.FireUpdate();
|
||||||
|
ConnectedFeedback.FireUpdate();
|
||||||
|
if (e.Client.IsConnected) {
|
||||||
|
// Tasks on connect
|
||||||
|
} else {
|
||||||
|
// Cleanup items from this session
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Communication_TextReceived(object sender, GenericCommMethodReceiveTextArgs args) {
|
||||||
|
try {
|
||||||
|
foreach (var Output in Outputs) {
|
||||||
|
Output.Api.Eisc.StringInput[Output.Join].StringValue = args.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new FormatException(string.Format("ERROR:{0}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EssentialComm : Device {
|
||||||
|
public EssentialCommConfig Properties;
|
||||||
|
|
||||||
|
public CommunicationGather PortGather { get; private set; }
|
||||||
|
public List<BridgeApiEisc> Apis {get; set;}
|
||||||
|
public Dictionary<string, StringFeedback> CommFeedbacks {get; private set; }
|
||||||
|
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||||
|
public Dictionary<uint, EssentialCommsPort> CommDictionary { get; private set; }
|
||||||
|
|
||||||
|
public EssentialComm(string key, string name, JToken properties) : base(key, name) {
|
||||||
|
Properties = JsonConvert.DeserializeObject<EssentialCommConfig>(properties.ToString());
|
||||||
|
CommFeedbacks = new Dictionary<string, StringFeedback>();
|
||||||
|
CommDictionary = new Dictionary<uint, EssentialCommsPort>();
|
||||||
|
Apis = new List<BridgeApiEisc>();
|
||||||
|
int commNumber = 1;
|
||||||
|
foreach (var commConfig in Properties.CommConnections) {
|
||||||
|
var commPort = new EssentialCommsPort(commConfig.control, string.Format("{0}-{1}", this.Key, commConfig.joinNumber));
|
||||||
|
CommDictionary.Add(commConfig.joinNumber, commPort);
|
||||||
|
|
||||||
|
commNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var Ipid in Properties.EiscApiIpids) {
|
||||||
|
var ApiEisc = new BridgeApiEisc(Ipid);
|
||||||
|
Apis.Add(ApiEisc);
|
||||||
|
foreach (var commConnection in CommDictionary) {
|
||||||
|
Debug.Console(2, "Joining Api{0} to comm {1}", Ipid, commConnection.Key);
|
||||||
|
var tempComm = commConnection.Value;
|
||||||
|
var tempJoin = (uint)commConnection.Key;
|
||||||
|
EssentialComApiMap ApiMap = new EssentialComApiMap(ApiEisc, (uint)tempJoin);
|
||||||
|
|
||||||
|
tempComm.Outputs.Add(ApiMap);
|
||||||
|
// Check for ApiMap Overide Values here
|
||||||
|
|
||||||
|
ApiEisc.Eisc.SetBoolSigAction(tempJoin, b => {if (b) { tempComm.Comm.Connect(); } else { tempComm.Comm.Disconnect(); }});
|
||||||
|
ApiEisc.Eisc.SetStringSigAction(tempJoin, s => tempComm.Comm.SendText(s));
|
||||||
|
|
||||||
|
tempComm.StatusFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[tempJoin]);
|
||||||
|
tempComm.ConnectedFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[tempJoin]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
ApiEisc.Eisc.Register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Debug.Console(2, "Name {0} Activated", this.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Debug.Console(0, "Bridge {0}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public class EssentialComApiMap {
|
||||||
|
public uint Join;
|
||||||
|
public BridgeApiEisc Api;
|
||||||
|
public uint connectJoin;
|
||||||
|
public EssentialComApiMap(BridgeApiEisc api, uint join) {
|
||||||
|
Join = join;
|
||||||
|
Api = api;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
150
PepperDashEssentials/Bridges/EssentialDM.cs
Normal file
150
PepperDashEssentials/Bridges/EssentialDM.cs
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials {
|
||||||
|
public class EssentialDM : PepperDash.Core.Device {
|
||||||
|
public EssentialDMProperties Properties;
|
||||||
|
public List<BridgeApiEisc> BridgeApiEiscs;
|
||||||
|
private PepperDash.Essentials.DM.DmChassisController DmSwitch;
|
||||||
|
private EssentialDMApiMap ApiMap = new EssentialDMApiMap();
|
||||||
|
public EssentialDM(string key, string name, JToken properties)
|
||||||
|
: base(key, name) {
|
||||||
|
Properties = JsonConvert.DeserializeObject<EssentialDMProperties>(properties.ToString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public override bool CustomActivate() {
|
||||||
|
// Create EiscApis
|
||||||
|
try {
|
||||||
|
foreach (var device in DeviceManager.AllDevices) {
|
||||||
|
if (device.Key == this.Properties.connectionDeviceKey) {
|
||||||
|
Debug.Console(2, "deviceKey {0} Matches", device.Key);
|
||||||
|
DmSwitch = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.DM.DmChassisController;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
else {
|
||||||
|
Debug.Console(2, "deviceKey {0} doesn't match", device.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Properties.EiscApiIpids != null) {
|
||||||
|
|
||||||
|
|
||||||
|
foreach (string Ipid in Properties.EiscApiIpids) {
|
||||||
|
var ApiEisc = new BridgeApiEisc(Ipid);
|
||||||
|
for (uint x = 1; x <= DmSwitch.Chassis.NumberOfInputs;x++ ) {
|
||||||
|
uint tempX = x;
|
||||||
|
Debug.Console(2, "Creating EiscActions {0}", tempX);
|
||||||
|
|
||||||
|
|
||||||
|
ApiEisc.Eisc.SetUShortSigAction(ApiMap.OutputVideoRoutes[tempX], u => DmSwitch.ExecuteSwitch(u, tempX, eRoutingSignalType.Video));
|
||||||
|
ApiEisc.Eisc.SetUShortSigAction(ApiMap.OutputAudioRoutes[tempX], u => DmSwitch.ExecuteSwitch(u, tempX, eRoutingSignalType.Audio));
|
||||||
|
|
||||||
|
|
||||||
|
if (DmSwitch.TxDictionary.ContainsKey(tempX)) {
|
||||||
|
Debug.Console(2, "Creating Tx Feedbacks {0}", tempX);
|
||||||
|
var TxKey = DmSwitch.TxDictionary[tempX];
|
||||||
|
var TxDevice = DeviceManager.GetDeviceForKey(TxKey) as DmTxControllerBase;
|
||||||
|
TxDevice.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxOnlineStatus[tempX]]);
|
||||||
|
TxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxVideoSyncStatus[tempX]]);
|
||||||
|
ApiEisc.Eisc.SetUShortSigAction((ApiMap.HdcpSupport[tempX]), u => TxDevice.SetHdcpSupportAll((ePdtHdcpSupport)(u)));
|
||||||
|
TxDevice.HdcpSupportAllFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.HdcpSupport[tempX]]);
|
||||||
|
ApiEisc.Eisc.UShortInput[ApiMap.HdcpSupportCapability[tempX]].UShortValue = TxDevice.HdcpSupportCapability;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DmSwitch.VideoInputSyncFeedbacks[tempX].LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.TxVideoSyncStatus[tempX]]);
|
||||||
|
}
|
||||||
|
if (DmSwitch.RxDictionary.ContainsKey(tempX)) {
|
||||||
|
Debug.Console(2, "Creating Rx Feedbacks {0}", tempX);
|
||||||
|
var RxKey = DmSwitch.RxDictionary[tempX];
|
||||||
|
var RxDevice = DeviceManager.GetDeviceForKey(RxKey) as DmRmcControllerBase;
|
||||||
|
RxDevice.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.RxOnlineStatus[tempX]]);
|
||||||
|
}
|
||||||
|
// DmSwitch.InputEndpointOnlineFeedbacks[(ushort)tempOutputNum].LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.OutputVideoRoutes[tempOutputNum]]);
|
||||||
|
DmSwitch.VideoOutputFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.OutputVideoRoutes[tempX]]);
|
||||||
|
DmSwitch.AudioOutputFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.OutputAudioRoutes[tempX]]);
|
||||||
|
DmSwitch.InputNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.InputNames[tempX]]);
|
||||||
|
DmSwitch.OutputNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.OutputNames[tempX]]);
|
||||||
|
DmSwitch.OutputRouteNameFeedbacks[(ushort)tempX].LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.OutputRouteNames[tempX]]);
|
||||||
|
}
|
||||||
|
DmSwitch.IsOnline.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.ChassisOnline]);
|
||||||
|
ApiEisc.Eisc.Register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Debug.Console(2, "Name {0} Activated", this.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Debug.Console(2, "BRidge {0}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class EssentialDMProperties {
|
||||||
|
public string connectionDeviceKey;
|
||||||
|
public string[] EiscApiIpids;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class EssentialDMApiMap {
|
||||||
|
public ushort ChassisOnline = 11;
|
||||||
|
public Dictionary<uint, ushort> OutputVideoRoutes;
|
||||||
|
public Dictionary<uint, ushort> OutputAudioRoutes;
|
||||||
|
public Dictionary<uint, ushort> TxOnlineStatus;
|
||||||
|
public Dictionary<uint, ushort> RxOnlineStatus;
|
||||||
|
public Dictionary<uint, ushort> TxVideoSyncStatus;
|
||||||
|
public Dictionary<uint, ushort> InputNames;
|
||||||
|
public Dictionary<uint, ushort> OutputNames;
|
||||||
|
public Dictionary<uint, ushort> OutputRouteNames;
|
||||||
|
public Dictionary<uint, ushort> HdcpSupport;
|
||||||
|
public Dictionary<uint, ushort> HdcpSupportCapability;
|
||||||
|
|
||||||
|
public EssentialDMApiMap() {
|
||||||
|
OutputVideoRoutes = new Dictionary<uint, ushort>();
|
||||||
|
OutputAudioRoutes = new Dictionary<uint, ushort>();
|
||||||
|
TxOnlineStatus = new Dictionary<uint, ushort>();
|
||||||
|
RxOnlineStatus = new Dictionary<uint, ushort>();
|
||||||
|
TxVideoSyncStatus = new Dictionary<uint, ushort>();
|
||||||
|
InputNames = new Dictionary<uint, ushort>();
|
||||||
|
OutputNames = new Dictionary<uint, ushort>();
|
||||||
|
OutputRouteNames = new Dictionary<uint, ushort>();
|
||||||
|
HdcpSupport = new Dictionary<uint, ushort>();
|
||||||
|
HdcpSupportCapability = new Dictionary<uint, ushort>();
|
||||||
|
|
||||||
|
for (uint x = 1; x <= 200; x++) {
|
||||||
|
// Debug.Console(0, "Init Value {0}", x);
|
||||||
|
uint tempNum = x;
|
||||||
|
HdcpSupportCapability[tempNum] = (ushort)(tempNum + 1200);
|
||||||
|
HdcpSupport[tempNum] = (ushort)(tempNum + 1000);
|
||||||
|
OutputVideoRoutes[tempNum] = (ushort)(tempNum + 100);
|
||||||
|
OutputAudioRoutes[tempNum] = (ushort)(tempNum + 300);
|
||||||
|
TxOnlineStatus[tempNum] = (ushort)(tempNum + 500);
|
||||||
|
RxOnlineStatus[tempNum] = (ushort)(tempNum + 700);
|
||||||
|
TxVideoSyncStatus[tempNum] = (ushort)(tempNum + 100);
|
||||||
|
InputNames[tempNum] = (ushort)(tempNum + 100);
|
||||||
|
OutputNames[tempNum] = (ushort)(tempNum + 300);
|
||||||
|
OutputRouteNames[tempNum] = (ushort)(tempNum + 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
217
PepperDashEssentials/Bridges/EssentialDsp.cs
Normal file
217
PepperDashEssentials/Bridges/EssentialDsp.cs
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials {
|
||||||
|
public class EssentialDsp : PepperDash.Core.Device {
|
||||||
|
public EssentialDspProperties Properties;
|
||||||
|
public List<BridgeApiEisc> BridgeApiEiscs;
|
||||||
|
private PepperDash.Essentials.Devices.Common.DSP.QscDsp Dsp;
|
||||||
|
private EssentialDspApiMap ApiMap = new EssentialDspApiMap();
|
||||||
|
public EssentialDsp(string key, string name, JToken properties)
|
||||||
|
: base(key, name) {
|
||||||
|
Properties = JsonConvert.DeserializeObject<EssentialDspProperties>(properties.ToString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public override bool CustomActivate() {
|
||||||
|
// Create EiscApis
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICommunicationMonitor comm = null;
|
||||||
|
foreach (var device in DeviceManager.AllDevices)
|
||||||
|
{
|
||||||
|
if (device.Key == this.Properties.connectionDeviceKey)
|
||||||
|
{
|
||||||
|
if (!(device is ICommunicationMonitor))
|
||||||
|
{
|
||||||
|
comm = device as ICommunicationMonitor;
|
||||||
|
}
|
||||||
|
Debug.Console(2, "deviceKey {0} Matches", device.Key);
|
||||||
|
Dsp = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.Devices.Common.DSP.QscDsp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(2, "deviceKey {0} doesn't match", device.Key);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Properties.EiscApiIpids != null && Dsp != null)
|
||||||
|
{
|
||||||
|
foreach (string Ipid in Properties.EiscApiIpids)
|
||||||
|
{
|
||||||
|
var ApiEisc = new BridgeApiEisc(Ipid);
|
||||||
|
Debug.Console(2, "Connecting EiscApi {0} to {1}", ApiEisc.Ipid, Dsp.Name);
|
||||||
|
ushort x = 1;
|
||||||
|
if (comm != null)
|
||||||
|
{
|
||||||
|
comm.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.Online]);
|
||||||
|
}
|
||||||
|
foreach (var channel in Dsp.LevelControlPoints)
|
||||||
|
{
|
||||||
|
//var QscChannel = channel.Value as PepperDash.Essentials.Devices.Common.DSP.QscDspLevelControl;
|
||||||
|
Debug.Console(2, "QscChannel {0} connect", x);
|
||||||
|
|
||||||
|
var genericChannel = channel.Value as IBasicVolumeWithFeedback;
|
||||||
|
if (channel.Value.Enabled)
|
||||||
|
{
|
||||||
|
ApiEisc.Eisc.StringInput[ApiMap.channelName[x]].StringValue = channel.Value.LevelCustomName;
|
||||||
|
ApiEisc.Eisc.UShortInput[ApiMap.channelType[x]].UShortValue = (ushort)channel.Value.Type;
|
||||||
|
|
||||||
|
genericChannel.MuteFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.channelMuteToggle[x]]);
|
||||||
|
genericChannel.VolumeLevelFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.channelVolume[x]]);
|
||||||
|
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.channelMuteToggle[x], () => genericChannel.MuteToggle());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.channelMuteOn[x], () => genericChannel.MuteOn());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.channelMuteOff[x], () => genericChannel.MuteOff());
|
||||||
|
|
||||||
|
ApiEisc.Eisc.SetBoolSigAction(ApiMap.channelVolumeUp[x], b => genericChannel.VolumeUp(b));
|
||||||
|
ApiEisc.Eisc.SetBoolSigAction(ApiMap.channelVolumeDown[x], b => genericChannel.VolumeDown(b));
|
||||||
|
|
||||||
|
ApiEisc.Eisc.SetUShortSigAction(ApiMap.channelVolume[x], u => genericChannel.SetVolume(u));
|
||||||
|
ApiEisc.Eisc.SetStringSigAction(ApiMap.presetString, s => Dsp.RunPreset(s));
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
|
||||||
|
}
|
||||||
|
x = 1;
|
||||||
|
foreach (var preset in Dsp.PresetList)
|
||||||
|
{
|
||||||
|
ApiEisc.Eisc.StringInput[ApiMap.presets[x]].StringValue = preset.label;
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.presets[x], () => Dsp.RunPresetNumber(x));
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
foreach (var dialer in Dsp.Dialers)
|
||||||
|
{
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad0, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num0));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad1, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num1));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad2, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num2));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad3, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num3));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad4, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num4));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad5, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num5));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad6, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num6));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad7, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num7));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad8, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num8));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Keypad9, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Num9));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadStar, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Star));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadPound, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Pound));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadClear, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Clear));
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.KeypadBackspace, () => dialer.Value.SendKeypad(PepperDash.Essentials.Devices.Common.DSP.QscDspDialer.eKeypadKeys.Backspace));
|
||||||
|
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.Dial, () => dialer.Value.Dial());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.DoNotDisturbToggle, () => dialer.Value.DoNotDisturbToggle());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.DoNotDisturbOn, () => dialer.Value.DoNotDisturbOn());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.DoNotDisturbOff, () => dialer.Value.DoNotDisturbOff());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.AutoAnswerToggle, () => dialer.Value.AutoAnswerToggle());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.AutoAnswerOn, () => dialer.Value.AutoAnswerOn());
|
||||||
|
ApiEisc.Eisc.SetSigTrueAction(ApiMap.AutoAnswerOff, () => dialer.Value.AutoAnswerOff());
|
||||||
|
|
||||||
|
dialer.Value.DoNotDisturbFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.DoNotDisturbToggle]);
|
||||||
|
dialer.Value.DoNotDisturbFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.DoNotDisturbOn]);
|
||||||
|
dialer.Value.DoNotDisturbFeedback.LinkComplementInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.DoNotDisturbOff]);
|
||||||
|
|
||||||
|
dialer.Value.AutoAnswerFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.AutoAnswerToggle]);
|
||||||
|
dialer.Value.AutoAnswerFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.AutoAnswerOn]);
|
||||||
|
dialer.Value.AutoAnswerFeedback.LinkComplementInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.AutoAnswerOff]);
|
||||||
|
|
||||||
|
dialer.Value.OffHookFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.Dial]);
|
||||||
|
dialer.Value.DialStringFeedback.LinkInputSig(ApiEisc.Eisc.StringInput[ApiMap.DialString]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Debug.Console(2, "Name {0} Activated", this.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Debug.Console(0, "Bridge {0}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class EssentialDspProperties {
|
||||||
|
public string connectionDeviceKey;
|
||||||
|
public string[] EiscApiIpids;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class EssentialDspApiMap {
|
||||||
|
public ushort Online = 1;
|
||||||
|
public ushort presetString = 2000;
|
||||||
|
public Dictionary<uint, ushort> channelMuteToggle;
|
||||||
|
public Dictionary<uint, ushort> channelMuteOn;
|
||||||
|
public Dictionary<uint, ushort> channelMuteOff;
|
||||||
|
public Dictionary<uint, ushort> channelVolume;
|
||||||
|
public Dictionary<uint, ushort> channelType;
|
||||||
|
public Dictionary<uint, ushort> channelName;
|
||||||
|
public Dictionary<uint, ushort> channelVolumeUp;
|
||||||
|
public Dictionary<uint, ushort> channelVolumeDown;
|
||||||
|
public Dictionary<uint, ushort> presets;
|
||||||
|
public ushort DialString = 3100;
|
||||||
|
public ushort Keypad0 = 3110;
|
||||||
|
public ushort Keypad1 = 3111;
|
||||||
|
public ushort Keypad2 = 3112;
|
||||||
|
public ushort Keypad3 = 3113;
|
||||||
|
public ushort Keypad4 = 3114;
|
||||||
|
public ushort Keypad5 = 3115;
|
||||||
|
public ushort Keypad6 = 3116;
|
||||||
|
public ushort Keypad7 = 3117;
|
||||||
|
public ushort Keypad8 = 3118;
|
||||||
|
public ushort Keypad9 = 3119;
|
||||||
|
public ushort KeypadStar = 3120;
|
||||||
|
public ushort KeypadPound = 3121;
|
||||||
|
public ushort KeypadClear = 3122;
|
||||||
|
public ushort KeypadBackspace = 3123;
|
||||||
|
public ushort Dial = 3124;
|
||||||
|
public ushort DoNotDisturbToggle = 3132;
|
||||||
|
public ushort DoNotDisturbOn = 3133;
|
||||||
|
public ushort DoNotDisturbOff = 3134;
|
||||||
|
public ushort AutoAnswerToggle = 3127;
|
||||||
|
public ushort AutoAnswerOn = 3125;
|
||||||
|
public ushort AutoAnswerOff = 3126;
|
||||||
|
|
||||||
|
public EssentialDspApiMap() {
|
||||||
|
channelMuteToggle = new Dictionary<uint, ushort>();
|
||||||
|
channelMuteOn = new Dictionary<uint, ushort>();
|
||||||
|
channelMuteOff = new Dictionary<uint, ushort>();
|
||||||
|
channelVolume = new Dictionary<uint, ushort>();
|
||||||
|
channelName = new Dictionary<uint, ushort>();
|
||||||
|
channelType = new Dictionary<uint, ushort>();
|
||||||
|
presets = new Dictionary<uint, ushort>();
|
||||||
|
channelVolumeUp = new Dictionary<uint, ushort>();
|
||||||
|
channelVolumeDown = new Dictionary<uint, ushort>();
|
||||||
|
for (uint x = 1; x <= 100; x++) {
|
||||||
|
uint tempNum = x;
|
||||||
|
presets[tempNum] = (ushort)(tempNum + 100);
|
||||||
|
channelMuteToggle[tempNum] = (ushort)(tempNum + 400);
|
||||||
|
channelMuteOn[tempNum] = (ushort)(tempNum + 600);
|
||||||
|
channelMuteOff[tempNum] = (ushort)(tempNum + 800);
|
||||||
|
channelVolume[tempNum] = (ushort)(tempNum + 200);
|
||||||
|
channelName[tempNum] = (ushort)(tempNum + 200);
|
||||||
|
channelType[tempNum] = (ushort)(tempNum + 400);
|
||||||
|
channelVolumeUp[tempNum] = (ushort)(tempNum + 1000);
|
||||||
|
channelVolumeDown[tempNum] = (ushort)(tempNum + 1200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
98
PepperDashEssentials/Bridges/EssentialTVOne.cs
Normal file
98
PepperDashEssentials/Bridges/EssentialTVOne.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsTVOne : PepperDash.Core.Device
|
||||||
|
{
|
||||||
|
public EssentialTVOneProperties Properties;
|
||||||
|
public List<BridgeApiEisc> BridgeApiEiscs;
|
||||||
|
private PepperDash.Essentials.Devices.Common.TVOneCorio TVOneCorio;
|
||||||
|
private EssentialsTVOneApiMap ApiMap = new EssentialsTVOneApiMap();
|
||||||
|
public EssentialsTVOne(string key, string name, JToken properties)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Properties = JsonConvert.DeserializeObject<EssentialTVOneProperties>(properties.ToString());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public override bool CustomActivate() {
|
||||||
|
// Create EiscApis
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var device in DeviceManager.AllDevices)
|
||||||
|
{
|
||||||
|
if (device.Key == this.Properties.connectionDeviceKey)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "deviceKey {0} Matches", device.Key);
|
||||||
|
TVOneCorio = DeviceManager.GetDeviceForKey(device.Key) as PepperDash.Essentials.Devices.Common.TVOneCorio;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(2, "deviceKey {0} doesn't match", device.Key);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Properties.EiscApiIpids != null && TVOneCorio != null)
|
||||||
|
{
|
||||||
|
foreach (string Ipid in Properties.EiscApiIpids)
|
||||||
|
{
|
||||||
|
var ApiEisc = new BridgeApiEisc(Ipid);
|
||||||
|
Debug.Console(2, "Connecting EiscApi {0} to {1}", ApiEisc.Ipid, TVOneCorio.Name);
|
||||||
|
ushort x = 1;
|
||||||
|
TVOneCorio.OnlineFeedback.LinkInputSig(ApiEisc.Eisc.BooleanInput[ApiMap.Online]);
|
||||||
|
ApiEisc.Eisc.SetUShortSigAction(ApiMap.CallPreset, u => TVOneCorio.CallPreset(u));
|
||||||
|
TVOneCorio.PresetFeedback.LinkInputSig(ApiEisc.Eisc.UShortInput[ApiMap.PresetFeedback]);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Debug.Console(2, "Name {0} Activated", this.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Debug.Console(0, "Bridge {0}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class EssentialTVOneProperties
|
||||||
|
{
|
||||||
|
public string connectionDeviceKey;
|
||||||
|
public string[] EiscApiIpids;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class EssentialsTVOneApiMap
|
||||||
|
{
|
||||||
|
public ushort CallPreset = 1;
|
||||||
|
public ushort PresetFeedback = 1;
|
||||||
|
public ushort Online = 1;
|
||||||
|
|
||||||
|
public EssentialsTVOneApiMap()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
74
PepperDashEssentials/Bridges/GenericLightingBridge.cs
Normal file
74
PepperDashEssentials/Bridges/GenericLightingBridge.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class GenericLightingApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this PepperDash.Essentials.Core.Lighting.LightingBase lightingDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
GenericLightingJoinMap joinMap = new GenericLightingJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
|
||||||
|
|
||||||
|
// GenericLighitng Actions & FeedBack
|
||||||
|
trilist.SetUShortSigAction(joinMap.SelectScene, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
|
||||||
|
|
||||||
|
int sceneIndex = 1;
|
||||||
|
foreach (var scene in lightingDevice.LightingScenes)
|
||||||
|
{
|
||||||
|
var tempIndex = sceneIndex - 1;
|
||||||
|
trilist.SetSigTrueAction((uint)(joinMap.LightingSceneOffset + sceneIndex), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[tempIndex]));
|
||||||
|
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)]);
|
||||||
|
trilist.StringInput[(uint)(joinMap.LightingSceneOffset + sceneIndex)].StringValue = scene.Name;
|
||||||
|
trilist.BooleanInput[(uint)(joinMap.ButtonVisibilityOffset + sceneIndex)].BoolValue = true;
|
||||||
|
sceneIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lightingDevice.GetType().Name.ToString() == "LutronQuantumArea")
|
||||||
|
{
|
||||||
|
var lutronDevice = lightingDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
|
||||||
|
lutronDevice.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
trilist.SetStringSigAction(joinMap.IntegrationIdSet, s => lutronDevice.IntegrationId = s);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ApiEisc.Eisc.SetStringSigAction(ApiMap.integrationID, (s) => { lutronLights.IntegrationId = s; });
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
var lutronLights = lightingDevice as PepperDash.Essentials.Devices.Common.Environment.Lutron.LutronQuantumArea;
|
||||||
|
|
||||||
|
|
||||||
|
for (uint i = 1; i <= lightingBase.CircuitCount; i++)
|
||||||
|
{
|
||||||
|
var circuit = i;
|
||||||
|
lightingBase.CircuitNameFeedbacks[circuit - 1].LinkInputSig(trilist.StringInput[joinMap.CircuitNames + circuit]);
|
||||||
|
lightingBase.CircuitIsCritical[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitIsCritical + circuit]);
|
||||||
|
lightingBase.CircuitState[circuit - 1].LinkInputSig(trilist.BooleanInput[joinMap.CircuitState + circuit]);
|
||||||
|
trilist.SetSigTrueAction(joinMap.CircuitCycle + circuit, () => lightingBase.CycleCircuit(circuit - 1));
|
||||||
|
trilist.SetSigTrueAction(joinMap.CircuitOnCmd + circuit, () => lightingBase.TurnOnCircuit(circuit - 1));
|
||||||
|
trilist.SetSigTrueAction(joinMap.CircuitOffCmd + circuit, () => lightingBase.TurnOffCircuit(circuit - 1));
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
PepperDashEssentials/Bridges/GenericRelayDeviceBridge.cs
Normal file
51
PepperDashEssentials/Bridges/GenericRelayDeviceBridge.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class GenericRelayDeviceApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this GenericRelayDevice relay, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
GenericRelayControllerJoinMap joinMap = new GenericRelayControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<GenericRelayControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
if (relay.RelayOutput == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, relay, "Unable to link device '{0}'. Relay is null", relay.Key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, relay, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.Relay, new Action<bool>(b =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
relay.CloseRelay();
|
||||||
|
else
|
||||||
|
relay.OpenRelay();
|
||||||
|
}));
|
||||||
|
|
||||||
|
// feedback for relay state
|
||||||
|
|
||||||
|
relay.OutputIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Relay]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Devices.Common.Occupancy;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class GlsOccupancySensorBaseControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this GlsOccupancySensorBaseController occController, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
GlsOccupancySensorBaseJoinMap joinMap = new GlsOccupancySensorBaseJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
#region Single and Dual Sensor Stuff
|
||||||
|
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
trilist.StringInput[joinMap.Name].StringValue = occController.Name;
|
||||||
|
|
||||||
|
trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) =>
|
||||||
|
{
|
||||||
|
if (args.DeviceOnLine)
|
||||||
|
{
|
||||||
|
trilist.StringInput[joinMap.Name].StringValue = occController.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Occupied status
|
||||||
|
trilist.SetSigTrueAction(joinMap.ForceOccupied, new Action(() => occController.ForceOccupied()));
|
||||||
|
trilist.SetSigTrueAction(joinMap.ForceVacant, new Action(() => occController.ForceVacant()));
|
||||||
|
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback]);
|
||||||
|
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback]);
|
||||||
|
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback]);
|
||||||
|
trilist.SetBoolSigAction(joinMap.EnableRawStates, new Action<bool>((b) => occController.EnableRawStates(b)));
|
||||||
|
|
||||||
|
// Timouts
|
||||||
|
trilist.SetUShortSigAction(joinMap.Timeout, new Action<ushort>((u) => occController.SetRemoteTimeout(u)));
|
||||||
|
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout]);
|
||||||
|
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback]);
|
||||||
|
|
||||||
|
// LED Flash
|
||||||
|
trilist.SetSigTrueAction(joinMap.EnableLedFlash, new Action(() => occController.SetLedFlashEnable(true)));
|
||||||
|
trilist.SetSigTrueAction(joinMap.DisableLedFlash, new Action(() => occController.SetLedFlashEnable(false)));
|
||||||
|
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash]);
|
||||||
|
|
||||||
|
// Short Timeout
|
||||||
|
trilist.SetSigTrueAction(joinMap.EnableShortTimeout, new Action(() => occController.SetShortTimeoutState(true)));
|
||||||
|
trilist.SetSigTrueAction(joinMap.DisableShortTimeout, new Action(() => occController.SetShortTimeoutState(false)));
|
||||||
|
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout]);
|
||||||
|
|
||||||
|
// PIR Sensor
|
||||||
|
trilist.SetSigTrueAction(joinMap.EnablePir, new Action(() => occController.SetPirEnable(true)));
|
||||||
|
trilist.SetSigTrueAction(joinMap.DisablePir, new Action(() => occController.SetPirEnable(false)));
|
||||||
|
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir]);
|
||||||
|
|
||||||
|
// PIR Sensitivity in Occupied State
|
||||||
|
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState, new Action<bool>((b) => occController.IncrementPirSensitivityInOccupiedState(b)));
|
||||||
|
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState, new Action<bool>((b) => occController.DecrementPirSensitivityInOccupiedState(b)));
|
||||||
|
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState]);
|
||||||
|
|
||||||
|
// PIR Sensitivity in Vacant State
|
||||||
|
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState, new Action<bool>((b) => occController.IncrementPirSensitivityInVacantState(b)));
|
||||||
|
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState, new Action<bool>((b) => occController.DecrementPirSensitivityInVacantState(b)));
|
||||||
|
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState]);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Dual Technology Sensor Stuff
|
||||||
|
var odtOccController = occController as GlsOdtOccupancySensorController;
|
||||||
|
|
||||||
|
if (odtOccController != null)
|
||||||
|
{
|
||||||
|
// OR When Vacated
|
||||||
|
trilist.SetBoolSigAction(joinMap.OrWhenVacated, new Action<bool>((b) => odtOccController.SetOrWhenVacatedState(b)));
|
||||||
|
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated]);
|
||||||
|
|
||||||
|
// AND When Vacated
|
||||||
|
trilist.SetBoolSigAction(joinMap.AndWhenVacated, new Action<bool>((b) => odtOccController.SetAndWhenVacatedState(b)));
|
||||||
|
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated]);
|
||||||
|
|
||||||
|
// Ultrasonic A Sensor
|
||||||
|
trilist.SetSigTrueAction(joinMap.EnableUsA, new Action(() => odtOccController.SetUsAEnable(true)));
|
||||||
|
trilist.SetSigTrueAction(joinMap.DisableUsA, new Action(() => odtOccController.SetUsAEnable(false)));
|
||||||
|
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA]);
|
||||||
|
|
||||||
|
// Ultrasonic B Sensor
|
||||||
|
trilist.SetSigTrueAction(joinMap.EnableUsB, new Action(() => odtOccController.SetUsBEnable(true)));
|
||||||
|
trilist.SetSigTrueAction(joinMap.DisableUsB, new Action(() => odtOccController.SetUsBEnable(false)));
|
||||||
|
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB]);
|
||||||
|
|
||||||
|
// US Sensitivity in Occupied State
|
||||||
|
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState, new Action<bool>((b) => odtOccController.IncrementUsSensitivityInOccupiedState(b)));
|
||||||
|
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState, new Action<bool>((b) => odtOccController.DecrementUsSensitivityInOccupiedState(b)));
|
||||||
|
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState]);
|
||||||
|
|
||||||
|
// US Sensitivity in Vacant State
|
||||||
|
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState, new Action<bool>((b) => odtOccController.IncrementUsSensitivityInVacantState(b)));
|
||||||
|
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState, new Action<bool>((b) => odtOccController.DecrementUsSensitivityInVacantState(b)));
|
||||||
|
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState]);
|
||||||
|
|
||||||
|
//Sensor Raw States
|
||||||
|
odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback]);
|
||||||
|
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback]);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs
Normal file
66
PepperDashEssentials/Bridges/HdMdxxxCEControllerBridge.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.DM;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||||
|
using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.DM;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class HdMdxxxCEControllerApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this HdMdxxxCEController hdMdPair, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
HdMdxxxCEControllerJoinMap joinMap = new HdMdxxxCEControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<HdMdxxxCEControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, hdMdPair, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
hdMdPair.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
hdMdPair.RemoteEndDetectedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RemoteEndDetected]);
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction(joinMap.AutoRouteOn, new Action(() => hdMdPair.AutoRouteOn()));
|
||||||
|
hdMdPair.AutoRouteOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AutoRouteOn]);
|
||||||
|
trilist.SetSigTrueAction(joinMap.AutoRouteOff, new Action(() => hdMdPair.AutoRouteOff()));
|
||||||
|
hdMdPair.AutoRouteOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.AutoRouteOff]);
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction(joinMap.PriorityRoutingOn, new Action(() => hdMdPair.PriorityRouteOn()));
|
||||||
|
hdMdPair.PriorityRoutingOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOn]);
|
||||||
|
trilist.SetSigTrueAction(joinMap.PriorityRoutingOff, new Action(() => hdMdPair.PriorityRouteOff()));
|
||||||
|
hdMdPair.PriorityRoutingOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PriorityRoutingOff]);
|
||||||
|
|
||||||
|
trilist.SetSigTrueAction(joinMap.InputOnScreenDisplayEnabled, new Action(() => hdMdPair.OnScreenDisplayEnable()));
|
||||||
|
hdMdPair.InputOnScreenDisplayEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayEnabled]);
|
||||||
|
trilist.SetSigTrueAction(joinMap.AutoRouteOff, new Action(() => hdMdPair.OnScreenDisplayDisable()));
|
||||||
|
hdMdPair.InputOnScreenDisplayEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.InputOnScreenDisplayDisabled]);
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.VideoSource, new Action<ushort>((i) => hdMdPair.ExecuteSwitch(i, null, eRoutingSignalType.Video | eRoutingSignalType.Audio)));
|
||||||
|
hdMdPair.VideoSourceFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoSource]);
|
||||||
|
|
||||||
|
trilist.UShortInput[joinMap.SourceCount].UShortValue = (ushort)hdMdPair.InputPorts.Count;
|
||||||
|
|
||||||
|
foreach (var input in hdMdPair.InputPorts)
|
||||||
|
{
|
||||||
|
var number = Convert.ToUInt16(input.Selector);
|
||||||
|
hdMdPair.SyncDetectedFeedbacks[number].LinkInputSig(trilist.BooleanInput[joinMap.SyncDetected + number]);
|
||||||
|
trilist.StringInput[joinMap.SourceNames + number].StringValue = input.Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs
Normal file
69
PepperDashEssentials/Bridges/IBasicCommunicationBridge.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class IBasicCommunicationApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this GenericComm comm, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
IBasicCommunicationJoinMap joinMap = new IBasicCommunicationJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<IBasicCommunicationJoinMap>(joinMapSerialized);
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
if (comm.CommPort == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, comm, "Unable to link device '{0}'. CommPort is null", comm.Key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, comm, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
// this is a permanent event handler. This cannot be -= from event
|
||||||
|
comm.CommPort.TextReceived += (s, a) =>
|
||||||
|
{
|
||||||
|
Debug.Console(2, comm, "RX: {0}", a.Text);
|
||||||
|
trilist.SetString(joinMap.TextReceived, a.Text);
|
||||||
|
};
|
||||||
|
trilist.SetStringSigAction(joinMap.SendText, new Action<string>(s => comm.CommPort.SendText(s)));
|
||||||
|
trilist.SetStringSigAction(joinMap.SetPortConfig, new Action<string>(s => comm.SetPortConfig(s)));
|
||||||
|
|
||||||
|
|
||||||
|
var sComm = comm.CommPort as ISocketStatus;
|
||||||
|
if (sComm != null)
|
||||||
|
{
|
||||||
|
sComm.ConnectionChange += (s, a) =>
|
||||||
|
{
|
||||||
|
trilist.SetUshort(joinMap.Status, (ushort)(a.Client.ClientStatus));
|
||||||
|
trilist.SetBool(joinMap.Connected, a.Client.ClientStatus ==
|
||||||
|
Crestron.SimplSharp.CrestronSockets.SocketStatus.SOCKET_STATUS_CONNECTED);
|
||||||
|
};
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.Connect, new Action<bool>(b =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
sComm.Connect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sComm.Disconnect();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
PepperDashEssentials/Bridges/IBridge.cs
Normal file
14
PepperDashEssentials/Bridges/IBridge.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a device that uses the legacy JoinMapBase for its join map
|
||||||
|
/// </summary>
|
||||||
|
[Obsolete("IBridgeAdvanced should be used going forward with JoinMapBaseAdvanced")]
|
||||||
|
public interface IBridge
|
||||||
|
{
|
||||||
|
void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
44
PepperDashEssentials/Bridges/IDigitalInputBridge.cs
Normal file
44
PepperDashEssentials/Bridges/IDigitalInputBridge.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class IDigitalInputApiExtenstions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this IDigitalInput input, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
IDigitalInputJoinMap joinMap = new IDigitalInputJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Debug.Console(1, input as Device, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
// Link feedback for input state
|
||||||
|
input.InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState]);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, input as Device, "Unable to link device '{0}'. Input is null", (input as Device).Key);
|
||||||
|
Debug.Console(1, input as Device, "Error: {0}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
128
PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs
Normal file
128
PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class IRSetTopBoxBaseApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this PepperDash.Essentials.Devices.Common.IRSetTopBoxBase stbDevice, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
SetTopBoxControllerJoinMap joinMap = new SetTopBoxControllerJoinMap();
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<SetTopBoxControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
Debug.Console(0, "Linking to Display: {0}", stbDevice.Name);
|
||||||
|
|
||||||
|
trilist.StringInput[joinMap.Name].StringValue = stbDevice.Name;
|
||||||
|
|
||||||
|
var stbBase = stbDevice as ISetTopBoxControls;
|
||||||
|
if (stbBase != null)
|
||||||
|
{
|
||||||
|
trilist.BooleanInput[joinMap.HasDpad].BoolValue = stbBase.HasDpad;
|
||||||
|
trilist.BooleanInput[joinMap.HasNumeric].BoolValue = stbBase.HasNumeric;
|
||||||
|
trilist.BooleanInput[joinMap.HasDvr].BoolValue = stbBase.HasDvr;
|
||||||
|
trilist.BooleanInput[joinMap.HasPresets].BoolValue = stbBase.HasPresets;
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.DvrList, (b) => stbBase.DvrList(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Replay, (b) => stbBase.Replay(b));
|
||||||
|
|
||||||
|
trilist.SetStringSigAction(joinMap.LoadPresets, (s) => stbBase.LoadPresets(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
var stbPower = stbDevice as IPower;
|
||||||
|
if (stbPower != null)
|
||||||
|
{
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOn, () => stbPower.PowerOn());
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerOff, () => stbPower.PowerOff());
|
||||||
|
trilist.SetSigTrueAction(joinMap.PowerToggle, () => stbPower.PowerToggle());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var stbDPad = stbDevice as IDPad;
|
||||||
|
if (stbDPad != null)
|
||||||
|
{
|
||||||
|
trilist.SetBoolSigAction(joinMap.Up, (b) => stbDPad.Up(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Down, (b) => stbDPad.Down(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Left, (b) => stbDPad.Left(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Right, (b) => stbDPad.Right(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Select, (b) => stbDPad.Select(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Menu, (b) => stbDPad.Menu(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Exit, (b) => stbDPad.Exit(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
var stbChannel = stbDevice as IChannel;
|
||||||
|
if (stbChannel != null)
|
||||||
|
{
|
||||||
|
trilist.SetBoolSigAction(joinMap.ChannelUp, (b) => stbChannel.ChannelUp(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.ChannelDown, (b) => stbChannel.ChannelDown(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.LastChannel, (b) => stbChannel.LastChannel(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Guide, (b) => stbChannel.Guide(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Info, (b) => stbChannel.Info(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Exit, (b) => stbChannel.Exit(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
var stbColor = stbDevice as IColor;
|
||||||
|
if (stbColor != null)
|
||||||
|
{
|
||||||
|
trilist.SetBoolSigAction(joinMap.Red, (b) => stbColor.Red(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Green, (b) => stbColor.Green(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Yellow, (b) => stbColor.Yellow(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Blue, (b) => stbColor.Blue(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
var stbKeypad = stbDevice as ISetTopBoxNumericKeypad;
|
||||||
|
if (stbKeypad != null)
|
||||||
|
{
|
||||||
|
trilist.StringInput[joinMap.KeypadAccessoryButton1Label].StringValue = stbKeypad.KeypadAccessoryButton1Label;
|
||||||
|
trilist.StringInput[joinMap.KeypadAccessoryButton2Label].StringValue = stbKeypad.KeypadAccessoryButton2Label;
|
||||||
|
|
||||||
|
trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1].BoolValue = stbKeypad.HasKeypadAccessoryButton1;
|
||||||
|
trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2].BoolValue = stbKeypad.HasKeypadAccessoryButton2;
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit0, (b) => stbKeypad.Digit0(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit1, (b) => stbKeypad.Digit1(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit2, (b) => stbKeypad.Digit2(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit3, (b) => stbKeypad.Digit3(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit4, (b) => stbKeypad.Digit4(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit5, (b) => stbKeypad.Digit5(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit6, (b) => stbKeypad.Digit6(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit7, (b) => stbKeypad.Digit7(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit8, (b) => stbKeypad.Digit8(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Digit9, (b) => stbKeypad.Digit9(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press, (b) => stbKeypad.KeypadAccessoryButton1(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press, (b) => stbKeypad.KeypadAccessoryButton1(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Dash, (b) => stbKeypad.Dash(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.KeypadEnter, (b) => stbKeypad.KeypadEnter(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
var stbTransport = stbDevice as ITransport;
|
||||||
|
if (stbTransport != null)
|
||||||
|
{
|
||||||
|
trilist.SetBoolSigAction(joinMap.Play, (b) => stbTransport.Play(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Pause, (b) => stbTransport.Pause(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Rewind, (b) => stbTransport.Rewind(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.FFwd, (b) => stbTransport.FFwd(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.ChapMinus, (b) => stbTransport.ChapMinus(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.ChapPlus, (b) => stbTransport.ChapPlus(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Stop, (b) => stbTransport.Stop(b));
|
||||||
|
trilist.SetBoolSigAction(joinMap.Record, (b) => stbTransport.Record(b));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class AirMediaControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the device is online when high
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the device is in session when high
|
||||||
|
/// </summary>
|
||||||
|
public uint IsInSession { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates sync detected on HDMI input when high
|
||||||
|
/// </summary>
|
||||||
|
public uint HdmiVideoSync { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Set High to enable automatic input routing and low to disable. Feedback high when enabled
|
||||||
|
/// </summary>
|
||||||
|
public uint AutomaticInputRoutingEnabled { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Selects source and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoOut { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Provided error feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint ErrorFB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates the number of connected users as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint NumberOfUsersConnectedFB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the login code and provides the current code as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint LoginCode { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the name defined in config as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the connection address as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint ConnectionAddressFB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the hostname as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint HostnameFB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the serial number as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint SerialNumberFeedback { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public AirMediaControllerJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 1;
|
||||||
|
IsInSession = 2;
|
||||||
|
HdmiVideoSync = 3;
|
||||||
|
AutomaticInputRoutingEnabled = 4;
|
||||||
|
|
||||||
|
// Analog
|
||||||
|
VideoOut = 1;
|
||||||
|
ErrorFB = 2;
|
||||||
|
NumberOfUsersConnectedFB = 3;
|
||||||
|
LoginCode = 4;
|
||||||
|
|
||||||
|
// Serial
|
||||||
|
Name = 1;
|
||||||
|
ConnectionAddressFB = 2;
|
||||||
|
HostnameFB = 3;
|
||||||
|
SerialNumberFeedback = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
IsInSession = IsInSession + joinOffset;
|
||||||
|
HdmiVideoSync = HdmiVideoSync + joinOffset;
|
||||||
|
AutomaticInputRoutingEnabled = AutomaticInputRoutingEnabled + joinOffset;
|
||||||
|
|
||||||
|
VideoOut = VideoOut + joinOffset;
|
||||||
|
ErrorFB = ErrorFB + joinOffset;
|
||||||
|
NumberOfUsersConnectedFB = NumberOfUsersConnectedFB + joinOffset;
|
||||||
|
LoginCode = LoginCode + joinOffset;
|
||||||
|
|
||||||
|
Name = Name + joinOffset;
|
||||||
|
ConnectionAddressFB = ConnectionAddressFB + joinOffset;
|
||||||
|
HostnameFB = HostnameFB + joinOffset;
|
||||||
|
SerialNumberFeedback = SerialNumberFeedback + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
PepperDashEssentials/Bridges/JoinMaps/AppleTvJoinMap.cs
Normal file
68
PepperDashEssentials/Bridges/JoinMaps/AppleTvJoinMap.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class AppleTvJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Sends up arrow command while high
|
||||||
|
/// </summary>
|
||||||
|
public uint UpArrow { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends down arrow command while high
|
||||||
|
/// </summary>
|
||||||
|
public uint DnArrow { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends left arrow command while high
|
||||||
|
/// </summary>
|
||||||
|
public uint LeftArrow { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends right arrow command while high
|
||||||
|
/// </summary>
|
||||||
|
public uint RightArrow { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends menu command
|
||||||
|
/// </summary>
|
||||||
|
public uint Menu { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends select command
|
||||||
|
/// </summary>
|
||||||
|
public uint Select { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends play/pause command
|
||||||
|
/// </summary>
|
||||||
|
public uint PlayPause { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public AppleTvJoinMap()
|
||||||
|
{
|
||||||
|
UpArrow = 1;
|
||||||
|
DnArrow = 2;
|
||||||
|
LeftArrow = 3;
|
||||||
|
RightArrow = 4;
|
||||||
|
Menu = 5;
|
||||||
|
Select = 6;
|
||||||
|
PlayPause = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
UpArrow = UpArrow + joinOffset;
|
||||||
|
DnArrow = DnArrow + joinOffset;
|
||||||
|
LeftArrow = LeftArrow + joinOffset;
|
||||||
|
RightArrow = RightArrow + joinOffset;
|
||||||
|
Menu = Menu + joinOffset;
|
||||||
|
Select = Select + joinOffset;
|
||||||
|
PlayPause = PlayPause + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class C2nRthsControllerJoinMap:JoinMapBase
|
||||||
|
{
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
public uint Name { get; set; }
|
||||||
|
public uint Temperature { get; set; }
|
||||||
|
public uint Humidity { get; set; }
|
||||||
|
public uint TemperatureFormat { get; set; }
|
||||||
|
|
||||||
|
public C2nRthsControllerJoinMap()
|
||||||
|
{
|
||||||
|
//digital
|
||||||
|
IsOnline = 1;
|
||||||
|
TemperatureFormat = 2;
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
Temperature = 2;
|
||||||
|
Humidity = 3;
|
||||||
|
|
||||||
|
//serial
|
||||||
|
Name = 1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
var properties =
|
||||||
|
GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof(uint)).ToList();
|
||||||
|
|
||||||
|
foreach (var propertyInfo in properties)
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(this, (uint)propertyInfo.GetValue(this, null) + joinOffset, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Join map for CameraBase devices
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class CameraControllerJoinMap : JoinMapBaseAdvanced
|
||||||
|
{
|
||||||
|
[JoinName("TiltUp")]
|
||||||
|
public JoinDataComplete TiltUp = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Tilt Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("TiltDown")]
|
||||||
|
public JoinDataComplete TiltDown = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "Tilt Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("PanLeft")]
|
||||||
|
public JoinDataComplete PanLeft = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "Pan Left", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("PanRight")]
|
||||||
|
public JoinDataComplete PanRight = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "Pan Right", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("ZoomIn")]
|
||||||
|
public JoinDataComplete ZoomIn = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "Zoom In", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("ZoomOut")]
|
||||||
|
public JoinDataComplete ZoomOut = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "Zoom Out", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
[JoinName("IsOnline")]
|
||||||
|
public JoinDataComplete IsOnline = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "Is Online", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("PowerOn")]
|
||||||
|
public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("PowerOff")]
|
||||||
|
public JoinDataComplete PowerOff = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
[JoinName("NumberOfPresets")]
|
||||||
|
public JoinDataComplete NumberOfPresets = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "Tells Essentials the number of defined presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||||
|
[JoinName("PresetRecallStart")]
|
||||||
|
public JoinDataComplete PresetRecallStart = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Recall Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("PresetLabelStart")]
|
||||||
|
public JoinDataComplete PresetLabelStart = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Label Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
|
||||||
|
[JoinName("PresetSaveStart")]
|
||||||
|
public JoinDataComplete PresetSaveStart = new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 20 }, new JoinMetadata() { Label = "Preset Save Start", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
[JoinName("CameraModeAuto")]
|
||||||
|
public JoinDataComplete CameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Auto", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("CameraModeManual")]
|
||||||
|
public JoinDataComplete CameraModeManual = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Manual", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("CameraModeOff")]
|
||||||
|
public JoinDataComplete CameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 53, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
[JoinName("SupportsCameraModeAuto")]
|
||||||
|
public JoinDataComplete SupportsCameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 55, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Camera Mode Auto", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("SupportsCameraModeOff")]
|
||||||
|
public JoinDataComplete SupportsCameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 56, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Camera Mode Off", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
[JoinName("SupportsPresets")]
|
||||||
|
public JoinDataComplete SupportsPresets = new JoinDataComplete(new JoinData() { JoinNumber = 57, JoinSpan = 1 }, new JoinMetadata() { Label = "Supports Presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||||
|
|
||||||
|
public CameraControllerJoinMap(uint joinStart)
|
||||||
|
: base(joinStart, typeof(CameraControllerJoinMap))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DigitalLoggerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
public uint CircuitNames { get; set; }
|
||||||
|
public uint CircuitState { get; set; }
|
||||||
|
public uint CircuitCycle { get; set; }
|
||||||
|
public uint CircuitIsCritical { get; set; }
|
||||||
|
public uint CircuitOnCmd { get; set; }
|
||||||
|
public uint CircuitOffCmd { get; set; }
|
||||||
|
|
||||||
|
public DigitalLoggerJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 9;
|
||||||
|
CircuitState = 0;
|
||||||
|
CircuitCycle = 0;
|
||||||
|
CircuitIsCritical = 10;
|
||||||
|
CircuitOnCmd = 10;
|
||||||
|
CircuitOffCmd = 20;
|
||||||
|
// Serial
|
||||||
|
CircuitNames = 0;
|
||||||
|
// Analog
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
CircuitNames = CircuitNames + joinOffset;
|
||||||
|
CircuitState = CircuitState + joinOffset;
|
||||||
|
CircuitCycle = CircuitCycle + joinOffset;
|
||||||
|
CircuitIsCritical = CircuitIsCritical + joinOffset;
|
||||||
|
CircuitOnCmd = CircuitOnCmd + joinOffset;
|
||||||
|
CircuitOffCmd = CircuitOffCmd + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DisplayControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Turns the display off and reports power off feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint PowerOff { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Turns the display on and repots power on feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint PowerOn { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the display device supports two way communication when high
|
||||||
|
/// </summary>
|
||||||
|
public uint IsTwoWayDisplay { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Increments the volume while high
|
||||||
|
/// </summary>
|
||||||
|
public uint VolumeUp { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Decrements teh volume while high
|
||||||
|
/// </summary>
|
||||||
|
public uint VolumeDown { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the mute state. Feedback is high when volume is muted
|
||||||
|
/// </summary>
|
||||||
|
public uint VolumeMute { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range of digital joins to select inputs and report current input as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint InputSelectOffset { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range of digital joins to report visibility for input buttons
|
||||||
|
/// </summary>
|
||||||
|
public uint ButtonVisibilityOffset { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High if the device is online
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Analog join to set the input and report current input as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint InputSelect { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the volume level and reports the current level as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint VolumeLevel { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the name of the display as defined in config as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range of serial joins that reports the names of the inputs as feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint InputNamesOffset { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public DisplayControllerJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 50;
|
||||||
|
PowerOff = 1;
|
||||||
|
PowerOn = 2;
|
||||||
|
IsTwoWayDisplay = 3;
|
||||||
|
VolumeUp = 5;
|
||||||
|
VolumeDown = 6;
|
||||||
|
VolumeMute = 7;
|
||||||
|
|
||||||
|
ButtonVisibilityOffset = 40;
|
||||||
|
InputSelectOffset = 10;
|
||||||
|
|
||||||
|
// Analog
|
||||||
|
InputSelect = 11;
|
||||||
|
VolumeLevel = 5;
|
||||||
|
|
||||||
|
// Serial
|
||||||
|
Name = 1;
|
||||||
|
InputNamesOffset = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
PowerOff = PowerOff + joinOffset;
|
||||||
|
PowerOn = PowerOn + joinOffset;
|
||||||
|
IsTwoWayDisplay = IsTwoWayDisplay + joinOffset;
|
||||||
|
ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset;
|
||||||
|
Name = Name + joinOffset;
|
||||||
|
InputNamesOffset = InputNamesOffset + joinOffset;
|
||||||
|
InputSelectOffset = InputSelectOffset + joinOffset;
|
||||||
|
|
||||||
|
InputSelect = InputSelect + joinOffset;
|
||||||
|
|
||||||
|
VolumeUp = VolumeUp + joinOffset;
|
||||||
|
VolumeDown = VolumeDown + joinOffset;
|
||||||
|
VolumeMute = VolumeMute + joinOffset;
|
||||||
|
VolumeLevel = VolumeLevel + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges {
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DmBladeChassisControllerJoinMap : JoinMapBase {
|
||||||
|
#region Digital/Analogs
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// High when device is online
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports video sync feedback for each input
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoSyncStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding input's endpoint is online
|
||||||
|
/// </summary>
|
||||||
|
public uint InputEndpointOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding output's endpoint is online
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputEndpointOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc.
|
||||||
|
/// </summary>
|
||||||
|
public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current video source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputVideo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current HDCP state for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint HdcpSupportState { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the highest supported HDCP state level for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint HdcpSupportCapability { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the name for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint InputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the name for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the name of the current video source for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputCurrentVideoInputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the current input resolution for each corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint InputCurrentResolution { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public DmBladeChassisControllerJoinMap() {
|
||||||
|
//Digital/Analog
|
||||||
|
|
||||||
|
//Digital
|
||||||
|
IsOnline = 11;
|
||||||
|
VideoSyncStatus = 100; //101-299
|
||||||
|
InputEndpointOnline = 500; //501-699
|
||||||
|
OutputEndpointOnline = 700; //701-899
|
||||||
|
TxAdvancedIsPresent = 1000; //1001-1199
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
OutputVideo = 100; //101-299
|
||||||
|
HdcpSupportState = 1000; //1001-1199
|
||||||
|
HdcpSupportCapability = 1200; //1201-1399
|
||||||
|
|
||||||
|
|
||||||
|
//Serial
|
||||||
|
InputNames = 100; //101-299
|
||||||
|
OutputNames = 300; //301-499
|
||||||
|
OutputCurrentVideoInputNames = 2000; //2001-2199
|
||||||
|
InputCurrentResolution = 2400; // 2401-2599
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart) {
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
OutputVideo = OutputVideo + joinOffset;
|
||||||
|
VideoSyncStatus = VideoSyncStatus + joinOffset;
|
||||||
|
InputNames = InputNames + joinOffset;
|
||||||
|
OutputNames = OutputNames + joinOffset;
|
||||||
|
OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset;
|
||||||
|
InputCurrentResolution = InputCurrentResolution + joinOffset;
|
||||||
|
InputEndpointOnline = InputEndpointOnline + joinOffset;
|
||||||
|
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
|
||||||
|
HdcpSupportState = HdcpSupportState + joinOffset;
|
||||||
|
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DmChassisControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digital/Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Analog input sets System ID, output reports current ID as feedback.
|
||||||
|
/// Digital input applies System ID, output is high when applying busy.
|
||||||
|
/// </summary>
|
||||||
|
public uint SystemId { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// High when device is online
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports video sync feedback for each input
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoSyncStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding input's endpoint is online
|
||||||
|
/// </summary>
|
||||||
|
public uint InputEndpointOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding output's endpoint is online
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputEndpointOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc.
|
||||||
|
/// </summary>
|
||||||
|
public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding output is disabled by HDCP.
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputDisabledByHdcp { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current video source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputVideo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current audio source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputAudio { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current Usb source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputUsb { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current Usb source for the corresponding input
|
||||||
|
/// </summary>
|
||||||
|
public uint InputUsb { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current HDCP state for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint HdcpSupportState { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the highest supported HDCP state level for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint HdcpSupportCapability { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint InputStreamCardStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputStreamCardStatus { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the name for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint InputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the name for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the name of the current video source for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputCurrentVideoInputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the name of the current audio source for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputCurrentAudioInputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the current input resolution for each corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint InputCurrentResolution { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public DmChassisControllerJoinMap()
|
||||||
|
{
|
||||||
|
//Digital/Analog
|
||||||
|
SystemId = 10; // Analog sets/gets SystemId, digital input applies and provides feedback of ID change busy
|
||||||
|
|
||||||
|
//Digital
|
||||||
|
IsOnline = 11;
|
||||||
|
VideoSyncStatus = 100; //101-299
|
||||||
|
InputEndpointOnline = 500; //501-699
|
||||||
|
OutputEndpointOnline = 700; //701-899
|
||||||
|
TxAdvancedIsPresent = 1000; //1001-1199
|
||||||
|
OutputDisabledByHdcp = 1200; //1201-1399
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
OutputVideo = 100; //101-299
|
||||||
|
OutputAudio = 300; //301-499
|
||||||
|
OutputUsb = 500; //501-699
|
||||||
|
InputUsb = 700; //701-899
|
||||||
|
HdcpSupportState = 1000; //1001-1199
|
||||||
|
HdcpSupportCapability = 1200; //1201-1399
|
||||||
|
InputStreamCardStatus = 1500; //1501-1532
|
||||||
|
OutputStreamCardStatus = 1600; //1601-1632
|
||||||
|
|
||||||
|
|
||||||
|
//Serial
|
||||||
|
InputNames = 100; //101-299
|
||||||
|
OutputNames = 300; //301-499
|
||||||
|
OutputCurrentVideoInputNames = 2000; //2001-2199
|
||||||
|
OutputCurrentAudioInputNames = 2200; //2201-2399
|
||||||
|
InputCurrentResolution = 2400; // 2401-2599
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
SystemId = SystemId + joinOffset;
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
OutputVideo = OutputVideo + joinOffset;
|
||||||
|
OutputAudio = OutputAudio + joinOffset;
|
||||||
|
OutputUsb = OutputUsb + joinOffset;
|
||||||
|
InputUsb = InputUsb + joinOffset;
|
||||||
|
VideoSyncStatus = VideoSyncStatus + joinOffset;
|
||||||
|
InputNames = InputNames + joinOffset;
|
||||||
|
OutputNames = OutputNames + joinOffset;
|
||||||
|
OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset;
|
||||||
|
OutputCurrentAudioInputNames = OutputCurrentAudioInputNames + joinOffset;
|
||||||
|
InputCurrentResolution = InputCurrentResolution + joinOffset;
|
||||||
|
InputEndpointOnline = InputEndpointOnline + joinOffset;
|
||||||
|
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
|
||||||
|
HdcpSupportState = HdcpSupportState + joinOffset;
|
||||||
|
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||||
|
InputStreamCardStatus = InputStreamCardStatus + joinOffset;
|
||||||
|
OutputStreamCardStatus = OutputStreamCardStatus + joinOffset;
|
||||||
|
OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset;
|
||||||
|
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DmRmcControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// High when device is online (if not attached to a DMP3 or DM chassis with a CPU3 card
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the current output resolution
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentOutputResolution { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the EDID manufacturer value
|
||||||
|
/// </summary>
|
||||||
|
public uint EdidManufacturer { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the EDID Name value
|
||||||
|
/// </summary>
|
||||||
|
public uint EdidName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the EDID preffered timing value
|
||||||
|
/// </summary>
|
||||||
|
public uint EdidPrefferedTiming { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the EDID serial number value
|
||||||
|
/// </summary>
|
||||||
|
public uint EdidSerialNumber { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
public uint AudioVideoSource { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public DmRmcControllerJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 1;
|
||||||
|
|
||||||
|
// Serial
|
||||||
|
CurrentOutputResolution = 1;
|
||||||
|
EdidManufacturer = 2;
|
||||||
|
EdidName = 3;
|
||||||
|
EdidPrefferedTiming = 4;
|
||||||
|
EdidSerialNumber = 5;
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
AudioVideoSource = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
CurrentOutputResolution = CurrentOutputResolution + joinOffset;
|
||||||
|
EdidManufacturer = EdidManufacturer + joinOffset;
|
||||||
|
EdidName = EdidName + joinOffset;
|
||||||
|
EdidPrefferedTiming = EdidPrefferedTiming + joinOffset;
|
||||||
|
EdidSerialNumber = EdidSerialNumber + joinOffset;
|
||||||
|
AudioVideoSource = AudioVideoSource + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
100
PepperDashEssentials/Bridges/JoinMaps/DmTxControllerJoinMap.cs
Normal file
100
PepperDashEssentials/Bridges/JoinMaps/DmTxControllerJoinMap.cs
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DmTxControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// High when device is online (if not attached to a DMP3 or DM chassis with a CPU3 card
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High when video sync is detected
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoSyncStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public uint FreeRunEnabled { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the video source
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoInput { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the audio source
|
||||||
|
/// </summary>
|
||||||
|
public uint AudioInput { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the highest supported HDCP state level for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint HdcpSupportCapability { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the current HDCP state for the corresponding input port
|
||||||
|
/// </summary>
|
||||||
|
public uint Port1HdcpState { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the current HDCP state for the corresponding input port
|
||||||
|
/// </summary>
|
||||||
|
public uint Port2HdcpState { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the current VGA Brightness level
|
||||||
|
/// </summary>
|
||||||
|
public uint VgaBrightness { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the current VGA Contrast level
|
||||||
|
/// </summary>
|
||||||
|
public uint VgaContrast { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the current input resolution
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentInputResolution { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public DmTxControllerJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 1;
|
||||||
|
VideoSyncStatus = 2;
|
||||||
|
FreeRunEnabled = 3;
|
||||||
|
// Serial
|
||||||
|
CurrentInputResolution = 1;
|
||||||
|
// Analog
|
||||||
|
VideoInput = 1;
|
||||||
|
AudioInput = 2;
|
||||||
|
HdcpSupportCapability = 3;
|
||||||
|
Port1HdcpState = 4;
|
||||||
|
Port2HdcpState = 5;
|
||||||
|
VgaBrightness = 6;
|
||||||
|
VgaContrast = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
VideoSyncStatus = VideoSyncStatus + joinOffset;
|
||||||
|
FreeRunEnabled = FreeRunEnabled + joinOffset;
|
||||||
|
CurrentInputResolution = CurrentInputResolution + joinOffset;
|
||||||
|
VideoInput = VideoInput + joinOffset;
|
||||||
|
AudioInput = AudioInput + joinOffset;
|
||||||
|
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||||
|
Port1HdcpState = Port1HdcpState + joinOffset;
|
||||||
|
Port2HdcpState = Port2HdcpState + joinOffset;
|
||||||
|
VgaBrightness = VgaBrightness + joinOffset;
|
||||||
|
VgaContrast = VgaContrast + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DmpsAudioOutputControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digital/Analog
|
||||||
|
/// <summary>
|
||||||
|
/// Range of joins for Master Volume
|
||||||
|
/// Analog join 1 is volume level and feedback
|
||||||
|
/// Digital join 1 is Mute on and feedback
|
||||||
|
/// Digital join 2 is Mute off and feedback
|
||||||
|
/// Digital join 3 is volume up
|
||||||
|
/// Digital join 4 is volume down
|
||||||
|
/// </summary>
|
||||||
|
public uint MasterVolume { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range of joins for Source Volume
|
||||||
|
/// Analog join 11 is volume level and feedback
|
||||||
|
/// Digital join 11 is Mute on and feedback
|
||||||
|
/// Digital join 12 is Mute off and feedback
|
||||||
|
/// Digital join 13 is volume up
|
||||||
|
/// Digital join 14 is volume down
|
||||||
|
/// </summary>
|
||||||
|
public uint SourceVolume { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range of joins for Codec1 Volume (if applicable)
|
||||||
|
/// Analog join 21 is volume level and feedback
|
||||||
|
/// Digital join 21 is Mute on and feedback
|
||||||
|
/// Digital join 22 is Mute off and feedback
|
||||||
|
/// Digital join 23 is volume up
|
||||||
|
/// Digital join 24 is volume down
|
||||||
|
/// </summary>
|
||||||
|
public uint Codec1Volume { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range of joins for Codec2 Volume (if applicable)
|
||||||
|
/// Analog join 31 is volume level and feedback
|
||||||
|
/// Digital join 31 is Mute on and feedback
|
||||||
|
/// Digital join 32 is Mute off and feedback
|
||||||
|
/// Digital join 33 is volume up
|
||||||
|
/// Digital join 34 is volume down
|
||||||
|
/// </summary>
|
||||||
|
public uint Codec2Volume { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public DmpsAudioOutputControllerJoinMap()
|
||||||
|
{
|
||||||
|
MasterVolume = 1; // 1-10
|
||||||
|
SourceVolume = 11; // 11-20
|
||||||
|
Codec1Volume = 21; // 21-30
|
||||||
|
Codec2Volume = 31; // 31-40
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart;
|
||||||
|
|
||||||
|
MasterVolume = MasterVolume + joinOffset;
|
||||||
|
SourceVolume = SourceVolume + joinOffset;
|
||||||
|
Codec1Volume = Codec1Volume + joinOffset;
|
||||||
|
Codec2Volume = Codec2Volume + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class DmpsRoutingControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports video sync feedback for each input
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoSyncStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding input's endpoint is online
|
||||||
|
/// </summary>
|
||||||
|
public uint InputEndpointOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports high if corresponding output's endpoint is online
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputEndpointOnline { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current video source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputVideo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current audio source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputAudio { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the current Usb source for the corresponding output
|
||||||
|
/// </summary>
|
||||||
|
//public uint OutputUsb { get; set; }
|
||||||
|
///// <summary>
|
||||||
|
///// Range sets and reports the current Usb source for the corresponding input
|
||||||
|
///// </summary>
|
||||||
|
//public uint InputUsb { get; set; }
|
||||||
|
///// <summary>
|
||||||
|
///// Range sets and reports the current HDCP state for the corresponding input card
|
||||||
|
///// </summary>
|
||||||
|
//public uint HdcpSupportState { get; set; }
|
||||||
|
///// <summary>
|
||||||
|
///// Range reports the highest supported HDCP state level for the corresponding input card
|
||||||
|
///// </summary>
|
||||||
|
//public uint HdcpSupportCapability { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the name for the corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint InputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range sets and reports the name for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the name of the current video source for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputCurrentVideoInputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the name of the current audio source for the corresponding output card
|
||||||
|
/// </summary>
|
||||||
|
public uint OutputCurrentAudioInputNames { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range reports the current input resolution for each corresponding input card
|
||||||
|
/// </summary>
|
||||||
|
public uint InputCurrentResolution { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public DmpsRoutingControllerJoinMap()
|
||||||
|
{
|
||||||
|
//Digital
|
||||||
|
VideoSyncStatus = 100; //101-299
|
||||||
|
InputEndpointOnline = 500; //501-699
|
||||||
|
OutputEndpointOnline = 700; //701-899
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
OutputVideo = 100; //101-299
|
||||||
|
OutputAudio = 300; //301-499
|
||||||
|
//OutputUsb = 500; //501-699
|
||||||
|
//InputUsb = 700; //701-899
|
||||||
|
VideoSyncStatus = 100; //101-299
|
||||||
|
//HdcpSupportState = 1000; //1001-1199
|
||||||
|
//HdcpSupportCapability = 1200; //1201-1399
|
||||||
|
|
||||||
|
|
||||||
|
//Serial
|
||||||
|
InputNames = 100; //101-299
|
||||||
|
OutputNames = 300; //301-499
|
||||||
|
OutputCurrentVideoInputNames = 2000; //2001-2199
|
||||||
|
OutputCurrentAudioInputNames = 2200; //2201-2399
|
||||||
|
InputCurrentResolution = 2400; // 2401-2599
|
||||||
|
InputEndpointOnline = 500; //501-699
|
||||||
|
OutputEndpointOnline = 700; //701-899
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
OutputVideo = OutputVideo + joinOffset;
|
||||||
|
OutputAudio = OutputAudio + joinOffset;
|
||||||
|
//OutputUsb = OutputUsb + joinOffset;
|
||||||
|
//InputUsb = InputUsb + joinOffset;
|
||||||
|
VideoSyncStatus = VideoSyncStatus + joinOffset;
|
||||||
|
InputNames = InputNames + joinOffset;
|
||||||
|
OutputNames = OutputNames + joinOffset;
|
||||||
|
OutputCurrentVideoInputNames = OutputCurrentVideoInputNames + joinOffset;
|
||||||
|
OutputCurrentAudioInputNames = OutputCurrentAudioInputNames + joinOffset;
|
||||||
|
InputCurrentResolution = InputCurrentResolution + joinOffset;
|
||||||
|
InputEndpointOnline = InputEndpointOnline + joinOffset;
|
||||||
|
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
|
||||||
|
//HdcpSupportState = HdcpSupportState + joinOffset;
|
||||||
|
//HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class GenericLightingJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
public uint SelectScene { get; set; }
|
||||||
|
public uint LightingSceneOffset { get; set; }
|
||||||
|
public uint ButtonVisibilityOffset { get; set; }
|
||||||
|
public uint IntegrationIdSet { get; set; }
|
||||||
|
|
||||||
|
public GenericLightingJoinMap()
|
||||||
|
{
|
||||||
|
// Digital
|
||||||
|
IsOnline = 1;
|
||||||
|
SelectScene = 1;
|
||||||
|
IntegrationIdSet = 1;
|
||||||
|
LightingSceneOffset = 10;
|
||||||
|
ButtonVisibilityOffset = 40;
|
||||||
|
// Analog
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
SelectScene = SelectScene + joinOffset;
|
||||||
|
LightingSceneOffset = LightingSceneOffset + joinOffset;
|
||||||
|
ButtonVisibilityOffset = ButtonVisibilityOffset + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class GenericRelayControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the state of the relay (High = closed, Low = Open)
|
||||||
|
/// </summary>
|
||||||
|
public uint Relay { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public GenericRelayControllerJoinMap()
|
||||||
|
{
|
||||||
|
Relay = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
Relay = Relay + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class GlsOccupancySensorBaseJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// High when device is online
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Forces the device to report occupied status
|
||||||
|
/// </summary>
|
||||||
|
public uint ForceOccupied { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Forces the device to report vacant status
|
||||||
|
/// </summary>
|
||||||
|
public uint ForceVacant { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Enables raw status reporting
|
||||||
|
/// </summary>
|
||||||
|
public uint EnableRawStates { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High when raw occupancy is detected
|
||||||
|
/// </summary>
|
||||||
|
public uint RawOccupancyFeedback { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High when PIR sensor detects motion
|
||||||
|
/// </summary>
|
||||||
|
public uint RawOccupancyPirFeedback { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High when US sensor detects motion
|
||||||
|
/// </summary>
|
||||||
|
public uint RawOccupancyUsFeedback { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High when occupancy is detected
|
||||||
|
/// </summary>
|
||||||
|
public uint RoomOccupiedFeedback { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Hich when occupancy is detected in the grace period
|
||||||
|
/// </summary>
|
||||||
|
public uint GraceOccupancyDetectedFeedback { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// High when vacancy is detected
|
||||||
|
/// </summary>
|
||||||
|
public uint RoomVacantFeedback { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the LED Flash when set high
|
||||||
|
/// </summary>
|
||||||
|
public uint EnableLedFlash { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the LED flash when set high
|
||||||
|
/// </summary>
|
||||||
|
public uint DisableLedFlash { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the Short Timeout
|
||||||
|
/// </summary>
|
||||||
|
public uint EnableShortTimeout { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the Short Timout
|
||||||
|
/// </summary>
|
||||||
|
public uint DisableShortTimeout { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Set high to enable one technology to trigger occupancy
|
||||||
|
/// </summary>
|
||||||
|
public uint OrWhenVacated { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Set high to require both technologies to trigger occupancy
|
||||||
|
/// </summary>
|
||||||
|
public uint AndWhenVacated { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Enables Ultrasonic Sensor A
|
||||||
|
/// </summary>
|
||||||
|
public uint EnableUsA { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Disables Ultrasonic Sensor A
|
||||||
|
/// </summary>
|
||||||
|
public uint DisableUsA { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Enables Ultrasonic Sensor B
|
||||||
|
/// </summary>
|
||||||
|
public uint EnableUsB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Disables Ultrasonic Sensor B
|
||||||
|
/// </summary>
|
||||||
|
public uint DisableUsB { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Enables Pir
|
||||||
|
/// </summary>
|
||||||
|
public uint EnablePir { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Disables Pir
|
||||||
|
/// </summary>
|
||||||
|
public uint DisablePir { get; set; }
|
||||||
|
public uint IncrementUsInOccupiedState { get; set; }
|
||||||
|
public uint DecrementUsInOccupiedState { get; set; }
|
||||||
|
public uint IncrementUsInVacantState { get; set; }
|
||||||
|
public uint DecrementUsInVacantState { get; set; }
|
||||||
|
public uint IncrementPirInOccupiedState { get; set; }
|
||||||
|
public uint DecrementPirInOccupiedState { get; set; }
|
||||||
|
public uint IncrementPirInVacantState { get; set; }
|
||||||
|
public uint DecrementPirInVacantState { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Sets adn reports the remote timeout value
|
||||||
|
/// </summary>
|
||||||
|
public uint Timeout { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the local timeout value
|
||||||
|
/// </summary>
|
||||||
|
public uint TimeoutLocalFeedback { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the minimum internal photo sensor value and reports the current level
|
||||||
|
/// </summary>
|
||||||
|
public uint InternalPhotoSensorValue { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the minimum external photo sensor value and reports the current level
|
||||||
|
/// </summary>
|
||||||
|
public uint ExternalPhotoSensorValue { get; set; }
|
||||||
|
|
||||||
|
public uint UsSensitivityInOccupiedState { get; set; }
|
||||||
|
|
||||||
|
public uint UsSensitivityInVacantState { get; set; }
|
||||||
|
|
||||||
|
public uint PirSensitivityInOccupiedState { get; set; }
|
||||||
|
|
||||||
|
public uint PirSensitivityInVacantState { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serial
|
||||||
|
public uint Name { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public GlsOccupancySensorBaseJoinMap()
|
||||||
|
{
|
||||||
|
IsOnline = 1;
|
||||||
|
ForceOccupied = 2;
|
||||||
|
ForceVacant = 3;
|
||||||
|
EnableRawStates = 4;
|
||||||
|
RoomOccupiedFeedback = 2;
|
||||||
|
GraceOccupancyDetectedFeedback = 3;
|
||||||
|
RoomVacantFeedback = 4;
|
||||||
|
RawOccupancyFeedback = 5;
|
||||||
|
RawOccupancyPirFeedback = 6;
|
||||||
|
RawOccupancyUsFeedback = 7;
|
||||||
|
EnableLedFlash = 11;
|
||||||
|
DisableLedFlash = 12;
|
||||||
|
EnableShortTimeout = 13;
|
||||||
|
DisableShortTimeout = 14;
|
||||||
|
OrWhenVacated = 15;
|
||||||
|
AndWhenVacated = 16;
|
||||||
|
EnableUsA = 17;
|
||||||
|
DisableUsA = 18;
|
||||||
|
EnableUsB = 19;
|
||||||
|
DisableUsB = 20;
|
||||||
|
EnablePir = 21;
|
||||||
|
DisablePir = 22;
|
||||||
|
IncrementUsInOccupiedState = 23;
|
||||||
|
DecrementUsInOccupiedState = 24;
|
||||||
|
IncrementUsInVacantState = 25;
|
||||||
|
DecrementUsInVacantState = 26;
|
||||||
|
IncrementPirInOccupiedState = 27;
|
||||||
|
DecrementPirInOccupiedState = 28;
|
||||||
|
IncrementPirInVacantState = 29;
|
||||||
|
DecrementPirInVacantState = 30;
|
||||||
|
|
||||||
|
Timeout = 1;
|
||||||
|
TimeoutLocalFeedback = 2;
|
||||||
|
InternalPhotoSensorValue = 3;
|
||||||
|
ExternalPhotoSensorValue = 4;
|
||||||
|
UsSensitivityInOccupiedState = 5;
|
||||||
|
UsSensitivityInVacantState = 6;
|
||||||
|
PirSensitivityInOccupiedState = 7;
|
||||||
|
PirSensitivityInVacantState = 8;
|
||||||
|
|
||||||
|
Name = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
ForceOccupied = ForceOccupied + joinOffset;
|
||||||
|
ForceVacant = ForceVacant + joinOffset;
|
||||||
|
EnableRawStates = EnableRawStates + joinOffset;
|
||||||
|
RoomOccupiedFeedback = RoomOccupiedFeedback + joinOffset;
|
||||||
|
GraceOccupancyDetectedFeedback = GraceOccupancyDetectedFeedback + joinOffset;
|
||||||
|
RoomVacantFeedback = RoomVacantFeedback + joinOffset;
|
||||||
|
RawOccupancyFeedback = RawOccupancyFeedback + joinOffset;
|
||||||
|
RawOccupancyPirFeedback = RawOccupancyPirFeedback + joinOffset;
|
||||||
|
RawOccupancyUsFeedback = RawOccupancyUsFeedback + joinOffset;
|
||||||
|
EnableLedFlash = EnableLedFlash + joinOffset;
|
||||||
|
DisableLedFlash = DisableLedFlash + joinOffset;
|
||||||
|
EnableShortTimeout = EnableShortTimeout + joinOffset;
|
||||||
|
DisableShortTimeout = DisableShortTimeout + joinOffset;
|
||||||
|
OrWhenVacated = OrWhenVacated + joinOffset;
|
||||||
|
AndWhenVacated = AndWhenVacated + joinOffset;
|
||||||
|
EnableUsA = EnableUsA + joinOffset;
|
||||||
|
DisableUsA = DisableUsA + joinOffset;
|
||||||
|
EnableUsB = EnableUsB + joinOffset;
|
||||||
|
DisableUsB = DisableUsB + joinOffset;
|
||||||
|
EnablePir = EnablePir + joinOffset;
|
||||||
|
DisablePir = DisablePir + joinOffset;
|
||||||
|
IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset;
|
||||||
|
DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset;
|
||||||
|
IncrementUsInVacantState = IncrementUsInVacantState + joinOffset;
|
||||||
|
DecrementUsInVacantState = DecrementUsInVacantState + joinOffset;
|
||||||
|
IncrementPirInOccupiedState = IncrementPirInOccupiedState + joinOffset;
|
||||||
|
DecrementPirInOccupiedState = DecrementPirInOccupiedState + joinOffset;
|
||||||
|
IncrementPirInVacantState = IncrementPirInVacantState + joinOffset;
|
||||||
|
DecrementPirInVacantState = DecrementPirInVacantState + joinOffset;
|
||||||
|
|
||||||
|
Timeout = Timeout + joinOffset;
|
||||||
|
TimeoutLocalFeedback = TimeoutLocalFeedback + joinOffset;
|
||||||
|
InternalPhotoSensorValue = InternalPhotoSensorValue + joinOffset;
|
||||||
|
ExternalPhotoSensorValue = ExternalPhotoSensorValue + joinOffset;
|
||||||
|
UsSensitivityInOccupiedState = UsSensitivityInOccupiedState + joinOffset;
|
||||||
|
UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset;
|
||||||
|
PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset;
|
||||||
|
PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset;
|
||||||
|
|
||||||
|
Name = Name + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class HdMdxxxCEControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// High when the pair is online
|
||||||
|
/// </summary>
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// High when the remote end device is online
|
||||||
|
/// </summary>
|
||||||
|
public uint RemoteEndDetected { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets Auto Route On and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint AutoRouteOn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets Auto Route Off and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint AutoRouteOff { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets Priority Routing On and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint PriorityRoutingOn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets Priority Routing Off and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint PriorityRoutingOff { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables OSD and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint InputOnScreenDisplayEnabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables OSD and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint InputOnScreenDisplayDisabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides Video Sync Detected feedback for each input
|
||||||
|
/// </summary>
|
||||||
|
public uint SyncDetected { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the video source for the receiver's HDMI out and provides feedback
|
||||||
|
/// </summary>
|
||||||
|
public uint VideoSource { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates the number of sources supported by the Tx/Rx pair
|
||||||
|
/// </summary>
|
||||||
|
public uint SourceCount { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates the name of each input port
|
||||||
|
/// </summary>
|
||||||
|
public uint SourceNames { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public HdMdxxxCEControllerJoinMap()
|
||||||
|
{
|
||||||
|
//Digital
|
||||||
|
IsOnline = 1;
|
||||||
|
RemoteEndDetected = 2;
|
||||||
|
AutoRouteOn = 3;
|
||||||
|
AutoRouteOff = 4;
|
||||||
|
PriorityRoutingOn = 5;
|
||||||
|
PriorityRoutingOff = 6;
|
||||||
|
InputOnScreenDisplayEnabled = 7;
|
||||||
|
InputOnScreenDisplayDisabled = 8;
|
||||||
|
SyncDetected = 10; // 11-15
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
VideoSource = 1;
|
||||||
|
SourceCount = 2;
|
||||||
|
|
||||||
|
//Serials
|
||||||
|
SourceNames = 10; // 11-15
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
IsOnline = IsOnline + joinOffset;
|
||||||
|
RemoteEndDetected = RemoteEndDetected + joinOffset;
|
||||||
|
AutoRouteOn = AutoRouteOn + joinOffset;
|
||||||
|
AutoRouteOff = AutoRouteOff + joinOffset;
|
||||||
|
PriorityRoutingOn = PriorityRoutingOn + joinOffset;
|
||||||
|
PriorityRoutingOff = PriorityRoutingOff + joinOffset;
|
||||||
|
InputOnScreenDisplayEnabled = InputOnScreenDisplayEnabled + joinOffset;
|
||||||
|
InputOnScreenDisplayDisabled = InputOnScreenDisplayDisabled + joinOffset;
|
||||||
|
SyncDetected = SyncDetected + joinOffset;
|
||||||
|
|
||||||
|
VideoSource = VideoSource + joinOffset;
|
||||||
|
SourceCount = SourceCount + joinOffset;
|
||||||
|
|
||||||
|
SourceNames = SourceNames + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class IBasicCommunicationJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Set High to connect, Low to disconnect
|
||||||
|
/// </summary>
|
||||||
|
public uint Connect { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports Connected State (High = Connected)
|
||||||
|
/// </summary>
|
||||||
|
public uint Connected { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the connections status value
|
||||||
|
/// </summary>
|
||||||
|
public uint Status { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Data back from port
|
||||||
|
/// </summary>
|
||||||
|
public uint TextReceived { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Sends data to the port
|
||||||
|
/// </summary>
|
||||||
|
public uint SendText { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Takes a JSON serialized string that sets a COM port's parameters
|
||||||
|
/// </summary>
|
||||||
|
public uint SetPortConfig { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public IBasicCommunicationJoinMap()
|
||||||
|
{
|
||||||
|
TextReceived = 1;
|
||||||
|
SendText = 1;
|
||||||
|
SetPortConfig = 2;
|
||||||
|
Connect = 1;
|
||||||
|
Connected = 1;
|
||||||
|
Status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
TextReceived = TextReceived + joinOffset;
|
||||||
|
SendText = SendText + joinOffset;
|
||||||
|
SetPortConfig = SetPortConfig + joinOffset;
|
||||||
|
Connect = Connect + joinOffset;
|
||||||
|
Connected = Connected + joinOffset;
|
||||||
|
Status = Status + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class IDigitalInputJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the state of the digital input
|
||||||
|
/// </summary>
|
||||||
|
public uint InputState { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public IDigitalInputJoinMap()
|
||||||
|
{
|
||||||
|
InputState = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
InputState = InputState + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class SetTopBoxControllerJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
#region Digitals
|
||||||
|
public uint DvrList { get; set; } //
|
||||||
|
public uint Replay { get; set; }
|
||||||
|
public uint Up { get; set; } //
|
||||||
|
public uint Down { get; set; } //
|
||||||
|
public uint Left { get; set; } //
|
||||||
|
public uint Right { get; set; } //
|
||||||
|
public uint Select { get; set; } //
|
||||||
|
public uint Menu { get; set; } //
|
||||||
|
public uint Exit { get; set; } //
|
||||||
|
public uint Digit0 { get; set; } //
|
||||||
|
public uint Digit1 { get; set; } //
|
||||||
|
public uint Digit2 { get; set; } //
|
||||||
|
public uint Digit3 { get; set; } //
|
||||||
|
public uint Digit4 { get; set; } //
|
||||||
|
public uint Digit5 { get; set; } //
|
||||||
|
public uint Digit6 { get; set; } //
|
||||||
|
public uint Digit7 { get; set; } //
|
||||||
|
public uint Digit8 { get; set; } //
|
||||||
|
public uint Digit9 { get; set; } //
|
||||||
|
public uint Dash { get; set; } //
|
||||||
|
public uint KeypadEnter { get; set; } //
|
||||||
|
public uint ChannelUp { get; set; } //
|
||||||
|
public uint ChannelDown { get; set; } //
|
||||||
|
public uint LastChannel { get; set; } //
|
||||||
|
public uint Guide { get; set; } //
|
||||||
|
public uint Info { get; set; } //
|
||||||
|
public uint Red { get; set; } //
|
||||||
|
public uint Green { get; set; } //
|
||||||
|
public uint Yellow { get; set; } //
|
||||||
|
public uint Blue { get; set; } //
|
||||||
|
public uint ChapMinus { get; set; }
|
||||||
|
public uint ChapPlus { get; set; }
|
||||||
|
public uint FFwd { get; set; } //
|
||||||
|
public uint Pause { get; set; } //
|
||||||
|
public uint Play { get; set; } //
|
||||||
|
public uint Record { get; set; }
|
||||||
|
public uint Rewind { get; set; } //
|
||||||
|
public uint Stop { get; set; } //
|
||||||
|
|
||||||
|
public uint PowerOn { get; set; } //
|
||||||
|
public uint PowerOff { get; set; } //
|
||||||
|
public uint PowerToggle { get; set; } //
|
||||||
|
|
||||||
|
public uint HasKeypadAccessoryButton1 { get; set; }
|
||||||
|
public uint HasKeypadAccessoryButton2 { get; set; }
|
||||||
|
|
||||||
|
public uint KeypadAccessoryButton1Press { get; set; }
|
||||||
|
public uint KeypadAccessoryButton2Press { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public uint HasDvr { get; set; }
|
||||||
|
public uint HasPresets { get; set; }
|
||||||
|
public uint HasNumeric { get; set; }
|
||||||
|
public uint HasDpad { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Strings
|
||||||
|
public uint Name { get; set; }
|
||||||
|
public uint LoadPresets { get; set; }
|
||||||
|
public uint KeypadAccessoryButton1Label { get; set; }
|
||||||
|
public uint KeypadAccessoryButton2Label { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public SetTopBoxControllerJoinMap()
|
||||||
|
{
|
||||||
|
PowerOn = 1;
|
||||||
|
PowerOff = 2;
|
||||||
|
PowerToggle = 3;
|
||||||
|
|
||||||
|
HasDpad = 4;
|
||||||
|
Up = 4;
|
||||||
|
Down = 5;
|
||||||
|
Left = 6;
|
||||||
|
Right = 7;
|
||||||
|
Select = 8;
|
||||||
|
Menu = 9;
|
||||||
|
Exit = 10;
|
||||||
|
|
||||||
|
HasNumeric = 11;
|
||||||
|
Digit0 = 11;
|
||||||
|
Digit1 = 12;
|
||||||
|
Digit2 = 13;
|
||||||
|
Digit3 = 14;
|
||||||
|
Digit4 = 15;
|
||||||
|
Digit5 = 16;
|
||||||
|
Digit6 = 17;
|
||||||
|
Digit7 = 18;
|
||||||
|
Digit8 = 19;
|
||||||
|
Digit9 = 20;
|
||||||
|
Dash = 21;
|
||||||
|
KeypadEnter = 22;
|
||||||
|
ChannelUp = 23;
|
||||||
|
ChannelDown = 24;
|
||||||
|
LastChannel = 25;
|
||||||
|
|
||||||
|
Guide = 26;
|
||||||
|
Info = 27;
|
||||||
|
Red = 28;
|
||||||
|
Green = 29;
|
||||||
|
Yellow = 30;
|
||||||
|
Blue = 31;
|
||||||
|
|
||||||
|
HasDvr = 32;
|
||||||
|
DvrList = 32;
|
||||||
|
Play = 33;
|
||||||
|
Pause = 34;
|
||||||
|
Stop = 35;
|
||||||
|
FFwd = 36;
|
||||||
|
Rewind = 37;
|
||||||
|
ChapPlus = 38;
|
||||||
|
ChapMinus = 39;
|
||||||
|
Replay = 40;
|
||||||
|
Record = 41;
|
||||||
|
HasKeypadAccessoryButton1 = 42;
|
||||||
|
KeypadAccessoryButton1Press = 42;
|
||||||
|
HasKeypadAccessoryButton2 = 43;
|
||||||
|
KeypadAccessoryButton2Press = 43;
|
||||||
|
|
||||||
|
Name = 1;
|
||||||
|
KeypadAccessoryButton1Label = 42;
|
||||||
|
KeypadAccessoryButton2Label = 43;
|
||||||
|
|
||||||
|
LoadPresets = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
PowerOn += joinOffset;
|
||||||
|
PowerOff += joinOffset;
|
||||||
|
PowerToggle += joinOffset;
|
||||||
|
|
||||||
|
HasDpad += joinOffset;
|
||||||
|
Up += joinOffset;
|
||||||
|
Down += joinOffset;
|
||||||
|
Left += joinOffset;
|
||||||
|
Right += joinOffset;
|
||||||
|
Select += joinOffset;
|
||||||
|
Menu += joinOffset;
|
||||||
|
Exit += joinOffset;
|
||||||
|
|
||||||
|
HasNumeric += joinOffset;
|
||||||
|
Digit0 += joinOffset;
|
||||||
|
Digit1 += joinOffset;
|
||||||
|
Digit2 += joinOffset;
|
||||||
|
Digit3 += joinOffset;
|
||||||
|
Digit4 += joinOffset;
|
||||||
|
Digit5 += joinOffset;
|
||||||
|
Digit6 += joinOffset;
|
||||||
|
Digit7 += joinOffset;
|
||||||
|
Digit8 += joinOffset;
|
||||||
|
Digit9 += joinOffset;
|
||||||
|
Dash += joinOffset;
|
||||||
|
KeypadEnter += joinOffset;
|
||||||
|
ChannelUp += joinOffset;
|
||||||
|
ChannelDown += joinOffset;
|
||||||
|
LastChannel += joinOffset;
|
||||||
|
|
||||||
|
Guide += joinOffset;
|
||||||
|
Info += joinOffset;
|
||||||
|
Red += joinOffset;
|
||||||
|
Green += joinOffset;
|
||||||
|
Yellow += joinOffset;
|
||||||
|
Blue += joinOffset;
|
||||||
|
|
||||||
|
HasDvr += joinOffset;
|
||||||
|
DvrList += joinOffset;
|
||||||
|
Play += joinOffset;
|
||||||
|
Pause += joinOffset;
|
||||||
|
Stop += joinOffset;
|
||||||
|
FFwd += joinOffset;
|
||||||
|
Rewind += joinOffset;
|
||||||
|
ChapPlus += joinOffset;
|
||||||
|
ChapMinus += joinOffset;
|
||||||
|
Replay += joinOffset;
|
||||||
|
Record += joinOffset;
|
||||||
|
HasKeypadAccessoryButton1 += joinOffset;
|
||||||
|
KeypadAccessoryButton1Press += joinOffset;
|
||||||
|
HasKeypadAccessoryButton2 += joinOffset;
|
||||||
|
KeypadAccessoryButton2Press += joinOffset;
|
||||||
|
|
||||||
|
Name += joinOffset;
|
||||||
|
KeypadAccessoryButton1Label += joinOffset;
|
||||||
|
KeypadAccessoryButton2Label += joinOffset;
|
||||||
|
|
||||||
|
LoadPresets += joinOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class StatusSignControllerJoinMap:JoinMapBase
|
||||||
|
{
|
||||||
|
public uint IsOnline { get; set; }
|
||||||
|
public uint Name { get; set; }
|
||||||
|
public uint RedLed { get; set; }
|
||||||
|
public uint GreenLed { get; set; }
|
||||||
|
public uint BlueLed { get; set; }
|
||||||
|
public uint RedControl { get; set; }
|
||||||
|
public uint GreenControl { get; set; }
|
||||||
|
public uint BlueControl { get; set; }
|
||||||
|
|
||||||
|
public StatusSignControllerJoinMap()
|
||||||
|
{
|
||||||
|
//digital
|
||||||
|
IsOnline = 1;
|
||||||
|
RedControl = 2;
|
||||||
|
GreenControl = 3;
|
||||||
|
BlueControl = 4;
|
||||||
|
|
||||||
|
//Analog
|
||||||
|
RedLed = 2;
|
||||||
|
GreenLed = 3;
|
||||||
|
BlueLed = 4;
|
||||||
|
|
||||||
|
//string
|
||||||
|
Name = 1;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
var properties =
|
||||||
|
GetType().GetCType().GetProperties().Where(p => p.PropertyType == typeof (uint)).ToList();
|
||||||
|
|
||||||
|
foreach (var propertyInfo in properties)
|
||||||
|
{
|
||||||
|
propertyInfo.SetValue(this, (uint) propertyInfo.GetValue(this, null) + joinOffset, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
227
PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs
Normal file
227
PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
using System;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Bridges
|
||||||
|
{
|
||||||
|
[Obsolete("Please use version PepperDash.Essentials.Core.Bridges")]
|
||||||
|
public class SystemMonitorJoinMap : JoinMapBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to indicate where the range of iterated program joins will start
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramStartJoin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset to indicate where the range of iterated Ethernet joins will start
|
||||||
|
/// </summary>
|
||||||
|
public uint EthernetStartJoin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset between each program join set
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramOffsetJoin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Offset between each Ethernet Interface join set
|
||||||
|
/// </summary>
|
||||||
|
public uint EthernetOffsetJoin { get; set; }
|
||||||
|
|
||||||
|
#region Digitals
|
||||||
|
/// <summary>
|
||||||
|
/// Range Sets and reports whether the corresponding program slot is started
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramStart { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range Sets and reports whether the corresponding program slot is stopped
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramStop { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range Sets and reports whether the corresponding program is registered
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramRegister { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Range Sets and reports whether the corresponding program is unregistered
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramUnregister { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Analogs
|
||||||
|
/// <summary>
|
||||||
|
/// Sets and reports the time zone
|
||||||
|
/// </summary>
|
||||||
|
public uint TimeZone { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serials
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the time zone name
|
||||||
|
/// </summary>
|
||||||
|
public uint TimeZoneName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the IO Controller Version
|
||||||
|
/// </summary>
|
||||||
|
public uint IOControllerVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the SNMP App Version
|
||||||
|
/// </summary>
|
||||||
|
public uint SnmpAppVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the BACnet App Version
|
||||||
|
/// </summary>
|
||||||
|
public uint BACnetAppVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the firmware version
|
||||||
|
/// </summary>
|
||||||
|
public uint ControllerVersion { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the name of the corresponding program
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the compile time of the corresponding program
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramCompiledTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Crestron Database version of the corresponding program
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramCrestronDatabaseVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Environment Version of the corresponding program
|
||||||
|
/// </summary>
|
||||||
|
public uint ProgramEnvironmentVersion { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Serialized JSON output that aggregates the program info of the corresponding program
|
||||||
|
/// </summary>
|
||||||
|
public uint AggregatedProgramInfo { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the controller serial number
|
||||||
|
/// </summary>
|
||||||
|
public uint SerialNumber { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the controller model
|
||||||
|
/// </summary>
|
||||||
|
public uint Model { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Host name set on the corresponding interface
|
||||||
|
/// </summary>
|
||||||
|
public uint HostName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Current IP address set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned address.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentIpAddress { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reporst the Current Default Gateway set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned gateway
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentDefaultGateway { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentSubnetMask { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Static IP address set on the corresponding interface. If DHCP is disabled, this will match the Current IP address
|
||||||
|
/// </summary>
|
||||||
|
public uint StaticIpAddress { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reporst the Static Default Gateway set on the corresponding interface. If DHCP is disabled, this will match the Current gateway
|
||||||
|
/// </summary>
|
||||||
|
public uint StaticDefaultGateway { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask
|
||||||
|
/// </summary>
|
||||||
|
public uint StaticSubnetMask { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the current DomainFeedback on the corresponding interface
|
||||||
|
/// </summary>
|
||||||
|
public uint Domain { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the current DNS Servers on the corresponding interface
|
||||||
|
/// </summary>
|
||||||
|
public uint DnsServer { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the MAC Address of the corresponding interface
|
||||||
|
/// </summary>
|
||||||
|
public uint MacAddress { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the DHCP Status of the corresponding interface
|
||||||
|
/// </summary>
|
||||||
|
public uint DhcpStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the current uptime. Updated in 5 minute intervals.
|
||||||
|
/// </summary>
|
||||||
|
public uint Uptime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports the date of the last boot
|
||||||
|
/// </summary>
|
||||||
|
public uint LastBoot { get; set; }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public SystemMonitorJoinMap()
|
||||||
|
{
|
||||||
|
TimeZone = 1;
|
||||||
|
|
||||||
|
TimeZoneName = 1;
|
||||||
|
IOControllerVersion = 2;
|
||||||
|
SnmpAppVersion = 3;
|
||||||
|
BACnetAppVersion = 4;
|
||||||
|
ControllerVersion = 5;
|
||||||
|
SerialNumber = 6;
|
||||||
|
Model = 7;
|
||||||
|
Uptime = 8;
|
||||||
|
LastBoot = 9;
|
||||||
|
|
||||||
|
|
||||||
|
ProgramStartJoin = 10;
|
||||||
|
|
||||||
|
ProgramOffsetJoin = 5;
|
||||||
|
|
||||||
|
// Offset in groups of 5 joins
|
||||||
|
ProgramStart = 1;
|
||||||
|
ProgramStop = 2;
|
||||||
|
ProgramRegister = 3;
|
||||||
|
ProgramUnregister = 4;
|
||||||
|
|
||||||
|
ProgramName = 1;
|
||||||
|
ProgramCompiledTime = 2;
|
||||||
|
ProgramCrestronDatabaseVersion = 3;
|
||||||
|
ProgramEnvironmentVersion = 4;
|
||||||
|
AggregatedProgramInfo = 5;
|
||||||
|
|
||||||
|
EthernetStartJoin = 75;
|
||||||
|
|
||||||
|
EthernetOffsetJoin = 15;
|
||||||
|
|
||||||
|
// Offset in groups of 15
|
||||||
|
HostName = 1;
|
||||||
|
CurrentIpAddress = 2;
|
||||||
|
CurrentSubnetMask = 3;
|
||||||
|
CurrentDefaultGateway = 4;
|
||||||
|
StaticIpAddress = 5;
|
||||||
|
StaticSubnetMask = 6;
|
||||||
|
StaticDefaultGateway = 7;
|
||||||
|
Domain = 8;
|
||||||
|
DnsServer = 9;
|
||||||
|
MacAddress = 10;
|
||||||
|
DhcpStatus = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OffsetJoinNumbers(uint joinStart)
|
||||||
|
{
|
||||||
|
var joinOffset = joinStart - 1;
|
||||||
|
|
||||||
|
TimeZone = TimeZone + joinOffset;
|
||||||
|
|
||||||
|
TimeZoneName = TimeZoneName + joinOffset;
|
||||||
|
IOControllerVersion = IOControllerVersion + joinOffset;
|
||||||
|
SnmpAppVersion = SnmpAppVersion + joinOffset;
|
||||||
|
BACnetAppVersion = BACnetAppVersion + joinOffset;
|
||||||
|
ControllerVersion = ControllerVersion + joinOffset;
|
||||||
|
|
||||||
|
// Sets the initial join value where the iterated program joins will begin
|
||||||
|
ProgramStartJoin = ProgramStartJoin + joinOffset;
|
||||||
|
EthernetStartJoin = EthernetStartJoin + joinOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
PepperDashEssentials/Bridges/StatusSignControllerBridge.cs
Normal file
65
PepperDashEssentials/Bridges/StatusSignControllerBridge.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class StatusSignDeviceApiExtensions
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this StatusSignController ssDevice, BasicTriList trilist, uint joinStart,
|
||||||
|
string joinMapKey)
|
||||||
|
{
|
||||||
|
var joinMap = new StatusSignControllerJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<StatusSignControllerJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, ssDevice, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(joinMap.RedControl, b => EnableControl(trilist, joinMap, ssDevice));
|
||||||
|
trilist.SetBoolSigAction(joinMap.GreenControl, b => EnableControl(trilist, joinMap, ssDevice));
|
||||||
|
trilist.SetBoolSigAction(joinMap.BlueControl, b => EnableControl(trilist, joinMap, ssDevice));
|
||||||
|
|
||||||
|
trilist.SetUShortSigAction(joinMap.RedLed, u => SetColor(trilist, joinMap, ssDevice));
|
||||||
|
trilist.SetUShortSigAction(joinMap.GreenLed, u => SetColor(trilist, joinMap, ssDevice));
|
||||||
|
trilist.SetUShortSigAction(joinMap.BlueLed, u => SetColor(trilist, joinMap, ssDevice));
|
||||||
|
|
||||||
|
trilist.StringInput[joinMap.Name].StringValue = ssDevice.Name;
|
||||||
|
|
||||||
|
ssDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]);
|
||||||
|
ssDevice.RedLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RedControl]);
|
||||||
|
ssDevice.BlueLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.BlueControl]);
|
||||||
|
ssDevice.GreenLedEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.GreenControl]);
|
||||||
|
|
||||||
|
ssDevice.RedLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.RedLed]);
|
||||||
|
ssDevice.BlueLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.BlueLed]);
|
||||||
|
ssDevice.GreenLedBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.GreenLed]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnableControl(BasicTriList triList, StatusSignControllerJoinMap joinMap,
|
||||||
|
StatusSignController device)
|
||||||
|
{
|
||||||
|
var redEnable = triList.BooleanOutput[joinMap.RedControl].BoolValue;
|
||||||
|
var greenEnable = triList.BooleanOutput[joinMap.GreenControl].BoolValue;
|
||||||
|
var blueEnable = triList.BooleanOutput[joinMap.BlueControl].BoolValue;
|
||||||
|
device.EnableLedControl(redEnable, greenEnable, blueEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetColor(BasicTriList triList, StatusSignControllerJoinMap joinMap,
|
||||||
|
StatusSignController device)
|
||||||
|
{
|
||||||
|
var redBrightness = triList.UShortOutput[joinMap.RedLed].UShortValue;
|
||||||
|
var greenBrightness = triList.UShortOutput[joinMap.GreenLed].UShortValue;
|
||||||
|
var blueBrightness = triList.UShortOutput[joinMap.BlueLed].UShortValue;
|
||||||
|
|
||||||
|
device.SetColor(redBrightness, greenBrightness, blueBrightness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
108
PepperDashEssentials/Bridges/SystemMonitorBridge.cs
Normal file
108
PepperDashEssentials/Bridges/SystemMonitorBridge.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Crestron.SimplSharpPro.Diagnostics;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Monitoring;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core.Bridges
|
||||||
|
{
|
||||||
|
public static class SystemMonitorBridge
|
||||||
|
{
|
||||||
|
public static void LinkToApi(this SystemMonitorController systemMonitorController, BasicTriList trilist, uint joinStart, string joinMapKey)
|
||||||
|
{
|
||||||
|
var joinMap = new SystemMonitorJoinMap();
|
||||||
|
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
joinMap = JsonConvert.DeserializeObject<SystemMonitorJoinMap>(joinMapSerialized);
|
||||||
|
|
||||||
|
joinMap.OffsetJoinNumbers(joinStart);
|
||||||
|
|
||||||
|
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||||
|
Debug.Console(2, systemMonitorController, "Linking API starting at join: {0}", joinStart);
|
||||||
|
|
||||||
|
systemMonitorController.TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone]);
|
||||||
|
systemMonitorController.TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName]);
|
||||||
|
|
||||||
|
systemMonitorController.IoControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]);
|
||||||
|
systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]);
|
||||||
|
systemMonitorController.BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]);
|
||||||
|
systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]);
|
||||||
|
systemMonitorController.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]);
|
||||||
|
systemMonitorController.ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]);
|
||||||
|
systemMonitorController.UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime]);
|
||||||
|
systemMonitorController.LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot]);
|
||||||
|
|
||||||
|
// iterate the program status feedback collection and map all the joins
|
||||||
|
LinkProgramInfoJoins(systemMonitorController, trilist, joinMap);
|
||||||
|
|
||||||
|
LinkEthernetInfoJoins(systemMonitorController, trilist, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap)
|
||||||
|
{
|
||||||
|
var ethernetSlotJoinStart = joinMap.EthernetStartJoin;
|
||||||
|
|
||||||
|
foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection)
|
||||||
|
{
|
||||||
|
fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress]);
|
||||||
|
fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask]);
|
||||||
|
fb.Value.CurrentDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentDefaultGateway]);
|
||||||
|
fb.Value.StaticIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticIpAddress]);
|
||||||
|
fb.Value.StaticSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticSubnetMask]);
|
||||||
|
fb.Value.StaticDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticDefaultGateway]);
|
||||||
|
fb.Value.HostNameFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.HostName]);
|
||||||
|
fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress]);
|
||||||
|
fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain]);
|
||||||
|
fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer]);
|
||||||
|
fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus]);
|
||||||
|
|
||||||
|
ethernetSlotJoinStart += joinMap.EthernetOffsetJoin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist,
|
||||||
|
SystemMonitorJoinMap joinMap)
|
||||||
|
{
|
||||||
|
var programSlotJoinStart = joinMap.ProgramStartJoin;
|
||||||
|
|
||||||
|
foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection)
|
||||||
|
{
|
||||||
|
var programNumber = p.Value.Program.Number;
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart,
|
||||||
|
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start);
|
||||||
|
p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]);
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop,
|
||||||
|
b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop);
|
||||||
|
p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]);
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister,
|
||||||
|
b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register);
|
||||||
|
p.Value.ProgramRegisteredFeedback.LinkInputSig(
|
||||||
|
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]);
|
||||||
|
|
||||||
|
trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister,
|
||||||
|
b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister);
|
||||||
|
p.Value.ProgramUnregisteredFeedback.LinkInputSig(
|
||||||
|
trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]);
|
||||||
|
|
||||||
|
p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]);
|
||||||
|
p.Value.ProgramCompileTimeFeedback.LinkInputSig(
|
||||||
|
trilist.StringInput[programSlotJoinStart + joinMap.ProgramCompiledTime]);
|
||||||
|
p.Value.CrestronDataBaseVersionFeedback.LinkInputSig(
|
||||||
|
trilist.StringInput[programSlotJoinStart + joinMap.ProgramCrestronDatabaseVersion]);
|
||||||
|
p.Value.EnvironmentVersionFeedback.LinkInputSig(
|
||||||
|
trilist.StringInput[programSlotJoinStart + joinMap.ProgramEnvironmentVersion]);
|
||||||
|
p.Value.AggregatedProgramInfoFeedback.LinkInputSig(
|
||||||
|
trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo]);
|
||||||
|
|
||||||
|
programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
72
PepperDashEssentials/Devices/Amplifier.cs
Normal file
72
PepperDashEssentials/Devices/Amplifier.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.Routing;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class Amplifier : EssentialsDevice, IRoutingSinkNoSwitching
|
||||||
|
{
|
||||||
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _CurrentSourceInfo;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSourceChange;
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public RoutingInputPort AudioIn { get; private set; }
|
||||||
|
|
||||||
|
public Amplifier(string key, string name)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
AudioIn = new RoutingInputPort(RoutingPortNames.AnyAudioIn, eRoutingSignalType.Audio,
|
||||||
|
eRoutingPortConnectionType.None, null, this);
|
||||||
|
InputPorts = new RoutingPortCollection<RoutingInputPort> { AudioIn };
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IRoutingInputs Members
|
||||||
|
|
||||||
|
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AmplifierFactory : EssentialsDeviceFactory<Amplifier>
|
||||||
|
{
|
||||||
|
public AmplifierFactory()
|
||||||
|
{
|
||||||
|
TypeNames = new List<string>() { "amplifier" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "Factory Attempting to create new Amplifier Device");
|
||||||
|
return new Amplifier(dc.Key, dc.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
"supportedSystemTypes": [
|
"supportedSystemTypes": [
|
||||||
"hudType",
|
"hudType",
|
||||||
"presType",
|
"presType",
|
||||||
"vtType",
|
"vtcType",
|
||||||
"custom"
|
"custom"
|
||||||
],
|
],
|
||||||
"type": "rmc3",
|
"type": "rmc3",
|
||||||
@@ -1,49 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using Crestron.SimplSharp;
|
||||||
using System.Linq;
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharpPro;
|
||||||
using Crestron.SimplSharp.CrestronIO;
|
using Crestron.SimplSharp.Reflection;
|
||||||
using Crestron.SimplSharpPro;
|
|
||||||
using System.Reflection;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using Newtonsoft.Json;
|
using PepperDash.Core;
|
||||||
using Newtonsoft.Json.Linq;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Core;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
using PepperDash.Essentials.Core.Config;
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
namespace PepperDash.Essentials
|
/// <summary>
|
||||||
{
|
/// Responsible for loading all of the device types for this library
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Responsible for loading all of the device types for this library
|
public class DeviceFactory
|
||||||
/// </summary>
|
{
|
||||||
public class DeviceFactory
|
|
||||||
{
|
public DeviceFactory()
|
||||||
|
{
|
||||||
public DeviceFactory()
|
var assy = Assembly.GetExecutingAssembly();
|
||||||
{
|
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
|
||||||
var assy = Assembly.GetExecutingAssembly();
|
|
||||||
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
|
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
|
||||||
|
|
||||||
var types = assy.GetTypes().Where(ct => typeof(IDeviceFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
|
if (types != null)
|
||||||
|
{
|
||||||
if (types != null)
|
foreach (var type in types)
|
||||||
{
|
{
|
||||||
foreach (var type in types)
|
try
|
||||||
{
|
{
|
||||||
try
|
var factory = (IDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||||
{
|
factory.LoadTypeFactories();
|
||||||
var factory = (IDeviceFactory)Activator.CreateInstance(type);
|
}
|
||||||
factory.LoadTypeFactories();
|
catch (Exception e)
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' DeviceFactory: {0}", e, type.Name);
|
||||||
{
|
}
|
||||||
Debug.LogMessage(Serilog.Events.LogEventLevel.Error, "Unable to load type: '{exception}' DeviceFactory: {factoryName}", e, type.Name);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,358 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharpPro;
|
||||||
|
using Crestron.SimplSharpPro.Fusion;
|
||||||
|
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.Fusion;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Fusion
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||||
|
{
|
||||||
|
BooleanSigData CodecIsInCall;
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1FusionController(IEssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||||
|
: base(room, ipId, joinMapKey)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called in base class constructor before RVI and GUID files are built
|
||||||
|
/// </summary>
|
||||||
|
protected override void ExecuteCustomSteps()
|
||||||
|
{
|
||||||
|
SetUpCodec();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||||
|
/// </summary>
|
||||||
|
void SetUpCodec()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
|
||||||
|
|
||||||
|
if (codec == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
codec.UsageTracker = new UsageTracking(codec);
|
||||||
|
codec.UsageTracker.UsageIsTracked = true;
|
||||||
|
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||||
|
|
||||||
|
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
|
||||||
|
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
|
||||||
|
|
||||||
|
// Map FusionRoom Attributes:
|
||||||
|
|
||||||
|
// Codec volume
|
||||||
|
var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig);
|
||||||
|
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||||
|
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
||||||
|
|
||||||
|
// In Call Status
|
||||||
|
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
|
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
||||||
|
|
||||||
|
// Online status
|
||||||
|
if (codec is ICommunicationMonitor)
|
||||||
|
{
|
||||||
|
var c = codec as ICommunicationMonitor;
|
||||||
|
var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
|
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||||
|
c.CommunicationMonitor.StatusChange += (o, a) =>
|
||||||
|
{
|
||||||
|
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
||||||
|
};
|
||||||
|
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.AttributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Codec IP Address
|
||||||
|
bool codecHasIpInfo = false;
|
||||||
|
var codecComm = codec.Communication;
|
||||||
|
|
||||||
|
string codecIpAddress = string.Empty;
|
||||||
|
int codecIpPort = 0;
|
||||||
|
|
||||||
|
StringSigData codecIpAddressSig;
|
||||||
|
StringSigData codecIpPortSig;
|
||||||
|
|
||||||
|
if(codecComm is GenericSshClient)
|
||||||
|
{
|
||||||
|
codecIpAddress = (codecComm as GenericSshClient).Hostname;
|
||||||
|
codecIpPort = (codecComm as GenericSshClient).Port;
|
||||||
|
codecHasIpInfo = true;
|
||||||
|
}
|
||||||
|
else if (codecComm is GenericTcpIpClient)
|
||||||
|
{
|
||||||
|
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
|
||||||
|
codecIpPort = (codecComm as GenericTcpIpClient).Port;
|
||||||
|
codecHasIpInfo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codecHasIpInfo)
|
||||||
|
{
|
||||||
|
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
|
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||||
|
|
||||||
|
codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
|
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempAsset = new FusionAsset();
|
||||||
|
|
||||||
|
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
|
||||||
|
|
||||||
|
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||||
|
{
|
||||||
|
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a new asset
|
||||||
|
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
|
||||||
|
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
|
||||||
|
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||||
|
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||||
|
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||||
|
|
||||||
|
// TODO: Map relevant attributes on asset symbol
|
||||||
|
|
||||||
|
codecAsset.TrySetMakeModel(codec);
|
||||||
|
codecAsset.TryLinkAssetErrorToCommunication(codec);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||||
|
{
|
||||||
|
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
|
||||||
|
|
||||||
|
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These methods are overridden because they access the room class which is of a different type
|
||||||
|
|
||||||
|
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
|
||||||
|
|
||||||
|
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||||
|
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||||
|
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
|
||||||
|
|
||||||
|
FusionRoom.Register();
|
||||||
|
|
||||||
|
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
|
||||||
|
|
||||||
|
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
|
||||||
|
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
|
||||||
|
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
// Room to fusion room
|
||||||
|
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||||
|
|
||||||
|
// Moved to
|
||||||
|
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
|
||||||
|
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||||
|
(Room as IEssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||||
|
|
||||||
|
|
||||||
|
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as IEssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||||
|
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||||
|
|
||||||
|
|
||||||
|
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SetUpSources()
|
||||||
|
{
|
||||||
|
// Sources
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as IEssentialsHuddleVtc1Room).SourceListKey);
|
||||||
|
if (dict != null)
|
||||||
|
{
|
||||||
|
// NEW PROCESS:
|
||||||
|
// Make these lists and insert the fusion attributes by iterating these
|
||||||
|
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
||||||
|
uint i = 1;
|
||||||
|
foreach (var kvp in setTopBoxes)
|
||||||
|
{
|
||||||
|
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
|
i++;
|
||||||
|
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
||||||
|
i = 1;
|
||||||
|
foreach (var kvp in discPlayers)
|
||||||
|
{
|
||||||
|
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
|
i++;
|
||||||
|
if (i > 5) // We only have five spots
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
|
||||||
|
i = 1;
|
||||||
|
foreach (var kvp in laptops)
|
||||||
|
{
|
||||||
|
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
|
i++;
|
||||||
|
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var kvp in dict)
|
||||||
|
{
|
||||||
|
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
|
||||||
|
|
||||||
|
if (usageDevice != null)
|
||||||
|
{
|
||||||
|
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
|
||||||
|
usageDevice.UsageTracker.UsageIsTracked = true;
|
||||||
|
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
|
||||||
|
(Room as IEssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SetUpDisplay()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Setup Display Usage Monitoring
|
||||||
|
|
||||||
|
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
||||||
|
|
||||||
|
// Consider updating this in multiple display systems
|
||||||
|
|
||||||
|
foreach (DisplayBase display in displays)
|
||||||
|
{
|
||||||
|
display.UsageTracker = new UsageTracking(display);
|
||||||
|
display.UsageTracker.UsageIsTracked = true;
|
||||||
|
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultDisplay = (Room as IEssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||||
|
if (defaultDisplay == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
|
||||||
|
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
|
||||||
|
|
||||||
|
// Display to fusion room sigs
|
||||||
|
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
|
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
|
|
||||||
|
var defaultDisplayTwoWay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||||
|
if (defaultDisplayTwoWay != null)
|
||||||
|
{
|
||||||
|
defaultDisplayTwoWay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultDisplay is IDisplayUsage)
|
||||||
|
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||||
|
|
||||||
|
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
|
||||||
|
|
||||||
|
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||||
|
|
||||||
|
//Check for existing asset in GUIDs collection
|
||||||
|
|
||||||
|
var tempAsset = new FusionAsset();
|
||||||
|
|
||||||
|
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||||
|
{
|
||||||
|
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a new asset
|
||||||
|
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
|
||||||
|
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||||
|
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
|
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
|
|
||||||
|
|
||||||
|
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||||
|
if (defaultTwoWayDisplay != null)
|
||||||
|
{
|
||||||
|
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||||
|
if (defaultDisplay is IDisplayUsage)
|
||||||
|
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||||
|
|
||||||
|
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use extension methods
|
||||||
|
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||||
|
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
|
||||||
|
{
|
||||||
|
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||||
|
|
||||||
|
|
||||||
|
if (display == (Room as IEssentialsHuddleVtc1Room).DefaultDisplay)
|
||||||
|
{
|
||||||
|
// Power on
|
||||||
|
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||||
|
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||||
|
|
||||||
|
// Power Off
|
||||||
|
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
|
||||||
|
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
|
||||||
|
|
||||||
|
var displayTwoWay = display as IHasPowerControlWithFeedback;
|
||||||
|
if (displayTwoWay != null)
|
||||||
|
{
|
||||||
|
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||||
|
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current Source
|
||||||
|
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||||
|
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.Fusion;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Fusion
|
||||||
|
{
|
||||||
|
public class EssentialsTechRoomFusionSystemController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||||
|
{
|
||||||
|
public EssentialsTechRoomFusionSystemController(EssentialsTechRoom room, uint ipId, string joinMapKey)
|
||||||
|
: base(room, ipId, joinMapKey)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SetUpDisplay()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var displays = (Room as EssentialsTechRoom).Displays;
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Setting up Static Assets for {0} Displays", displays.Count);
|
||||||
|
|
||||||
|
foreach (var display in displays.Values.Cast<DisplayBase>())
|
||||||
|
{
|
||||||
|
var disp = display; // Local scope variable
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Setting up Static Asset for {0}", disp.Key);
|
||||||
|
|
||||||
|
disp.UsageTracker = new UsageTracking(disp) { UsageIsTracked = true };
|
||||||
|
disp.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||||
|
|
||||||
|
var dispPowerOnAction = new Action<bool>(b =>
|
||||||
|
{
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
disp.PowerOn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var dispPowerOffAction = new Action<bool>(b =>
|
||||||
|
{
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
disp.PowerOff();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(disp.Key);
|
||||||
|
|
||||||
|
FusionAsset tempAsset;
|
||||||
|
|
||||||
|
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||||
|
{
|
||||||
|
// Used existing asset
|
||||||
|
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create a new asset
|
||||||
|
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
|
||||||
|
disp.Name, "Display", "");
|
||||||
|
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||||
|
tempAsset.InstanceId);
|
||||||
|
|
||||||
|
if (dispAsset != null)
|
||||||
|
{
|
||||||
|
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
|
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
|
|
||||||
|
// Use extension methods
|
||||||
|
dispAsset.TrySetMakeModel(disp);
|
||||||
|
dispAsset.TryLinkAssetErrorToCommunication(disp);
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultTwoWayDisplay = disp as IHasPowerControlWithFeedback;
|
||||||
|
if (defaultTwoWayDisplay != null)
|
||||||
|
{
|
||||||
|
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||||
|
if (disp is IDisplayUsage)
|
||||||
|
{
|
||||||
|
(disp as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dispAsset != null)
|
||||||
|
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error setting up displays in Fusion: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1415
PepperDashEssentials/Fusion/FusionSystemController.cs.orig
Normal file
1415
PepperDashEssentials/Fusion/FusionSystemController.cs.orig
Normal file
File diff suppressed because it is too large
Load Diff
19857
PepperDashEssentials/PepperDash Essentials TSW-760.sgd
Normal file
19857
PepperDashEssentials/PepperDash Essentials TSW-760.sgd
Normal file
File diff suppressed because it is too large
Load Diff
233
PepperDashEssentials/PepperDashEssentials.csproj
Normal file
233
PepperDashEssentials/PepperDashEssentials.csproj
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
<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>{1BED5BA9-88C4-4365-9362-6F4B128071D3}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>PepperDashEssentials</RootNamespace>
|
||||||
|
<AssemblyName>PepperDashEssentials</AssemblyName>
|
||||||
|
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92230};{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.42.30563, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\packages\PepperDashCore\lib\net35\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>
|
||||||
|
</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>
|
||||||
|
</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.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
|
||||||
|
</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="SimplSharpTimerEventInterface, Version=1.0.6197.20052, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Audio\EssentialsVolumeLevelConfig.cs" />
|
||||||
|
<Compile Include="Bridges\EiscBridge.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\AirMediaControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\AppleTvJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\BridgeFactory.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\CameraControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DigitalLoggerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DisplayControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DmBladeChassisControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DmChassisControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DmpsAudioOutputControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DmpsRoutingControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DmRmcControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\DmTxControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\GenericLightingJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\GenericRelayControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\GlsOccupancySensorBaseJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\HdMdxxxCEControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\IBasicCommunicationJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\IBridge.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\IDigitalInputJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\SetTopBoxControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
|
||||||
|
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
|
||||||
|
<Compile Include="Factory\DeviceFactory.cs" />
|
||||||
|
<Compile Include="Devices\Amplifier.cs" />
|
||||||
|
<Compile Include="ControlSystem.cs" />
|
||||||
|
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||||
|
<Compile Include="Fusion\EssentialsTechRoomFusionSystemController.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\SimplRoomPropertiesConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsTechRoomConfig.cs" />
|
||||||
|
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
|
||||||
|
<Compile Include="Room\Types\EssentialsCombinedHuddleVtc1Room.cs" />
|
||||||
|
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
|
||||||
|
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
|
||||||
|
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||||
|
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
||||||
|
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
|
||||||
|
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleSpaceRoom.cs" />
|
||||||
|
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleVtc1Room.cs" />
|
||||||
|
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\Essentials\EssentialsHeaderDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\JoinedSigInterlock.cs" />
|
||||||
|
<Compile Include="UIDrivers\ScreenSaverController.cs" />
|
||||||
|
<Compile Include="UIDrivers\SigInterlock.cs" />
|
||||||
|
<Compile Include="UIDrivers\EssentialsHuddleVTC\EssentialsHuddlePresentationUiDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\EssentialsHuddle\EssentialsHuddleTechPageDriver.cs" />
|
||||||
|
<Compile Include="UI\HttpLogoServer.cs" />
|
||||||
|
<Compile Include="UI\SmartObjectHeaderButtonList.cs" />
|
||||||
|
<Compile Include="UI\SubpageReferenceListCallStagingItem.cs" />
|
||||||
|
<Compile Include="UIDrivers\VC\EssentialsVideoCodecUiDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\EssentialsHuddleVTC\EssentialsHuddleVtc1PanelAvFunctionsDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\SourceChangeArgs.cs" />
|
||||||
|
<Compile Include="UI\JoinConstants\UISmartObjectJoin.cs" />
|
||||||
|
<Compile Include="UI\JoinConstants\UIStringlJoin.cs" />
|
||||||
|
<Compile Include="UI\JoinConstants\UIUshortJoin.cs" />
|
||||||
|
<Compile Include="UIDrivers\DualDisplayRouting.cs" />
|
||||||
|
<Compile Include="UIDrivers\Essentials\EssentialsPresentationPanelAvFunctionsDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\Page Drivers\SingleSubpageModalDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\Essentials\EssentialsPanelMainInterfaceDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\enums and base.cs" />
|
||||||
|
<Compile Include="UIDrivers\EssentialsHuddle\EssentialsHuddlePanelAvFunctionsDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\Page Drivers\SingleSubpageModalAndBackDriver.cs" />
|
||||||
|
<Compile Include="UIDrivers\SmartObjectRoomsList.cs" />
|
||||||
|
<Compile Include="UI\JoinConstants\UIBoolJoin.cs" />
|
||||||
|
<Compile Include="UI\DualDisplaySourceSRLController.cs" />
|
||||||
|
<Compile Include="UI\SubpageReferenceListActivityItem.cs" />
|
||||||
|
<Compile Include="Room\Types\EssentialsHuddleSpaceRoom.cs" />
|
||||||
|
<Compile Include="UI\EssentialsTouchpanelController.cs" />
|
||||||
|
<Compile Include="UI\SubpageReferenceListSourceItem.cs" />
|
||||||
|
<None Include="app.config" />
|
||||||
|
<EmbeddedResource Include="Example Configuration\EssentialsHuddleSpaceRoom\configurationFile-HuddleSpace-2-Source.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Example Configuration\EssentialsHuddleVtc1Room\configurationFile-mockVideoCodec_din-ap3_-_dm4x1.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Example Configuration\SIMPLBridging\configurationFile-dmps3300c-avRouting.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Example Configuration\SIMPLBridging\SIMPLBridgeExample_configurationFile.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<None Include="Properties\ControlSystem.cfg" />
|
||||||
|
<EmbeddedResource Include="SGD\PepperDash Essentials iPad.sgd">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="SGD\PepperDash Essentials TSW-560.sgd">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="SGD\PepperDash Essentials TSW-760.sgd">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\essentials-framework\Essentials Core\PepperDashEssentialsBase\PepperDash_Essentials_Core.csproj">
|
||||||
|
<Project>{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}</Project>
|
||||||
|
<Name>PepperDash_Essentials_Core</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\essentials-framework\Essentials Devices Common\Essentials Devices Common\Essentials Devices Common.csproj">
|
||||||
|
<Project>{892B761C-E479-44CE-BD74-243E9214AF13}</Project>
|
||||||
|
<Name>Essentials Devices Common</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\essentials-framework\Essentials DM\Essentials_DM\PepperDash_Essentials_DM.csproj">
|
||||||
|
<Project>{9199CE8A-0C9F-4952-8672-3EED798B284F}</Project>
|
||||||
|
<Name>PepperDash_Essentials_DM</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</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>
|
||||||
491
PepperDashEssentials/PluginLoading/PluginLoading.cs
Normal file
491
PepperDashEssentials/PluginLoading/PluginLoading.cs
Normal file
@@ -0,0 +1,491 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.CrestronIO;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Plugins;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Deals with loading plugins at runtime
|
||||||
|
/// </summary>
|
||||||
|
public static class PluginLoader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The complete list of loaded assemblies. Includes Essentials Framework assemblies and plugins
|
||||||
|
/// </summary>
|
||||||
|
public static List<LoadedAssembly> LoadedAssemblies { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of assemblies loaded from the plugins folder
|
||||||
|
/// </summary>
|
||||||
|
static List<LoadedAssembly> LoadedPluginFolderAssemblies;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The directory to look in for .cplz plugin packages
|
||||||
|
/// </summary>
|
||||||
|
static string _pluginDirectory = Global.FilePathPrefix + "plugins";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The directory where plugins will be moved to and loaded from
|
||||||
|
/// </summary>
|
||||||
|
static string _loadedPluginsDirectoryPath = _pluginDirectory + Global.DirectorySeparator + "loadedAssemblies";
|
||||||
|
|
||||||
|
// The temp directory where .cplz archives will be unzipped to
|
||||||
|
static string _tempDirectory = _pluginDirectory + Global.DirectorySeparator + "temp";
|
||||||
|
|
||||||
|
static PluginLoader()
|
||||||
|
{
|
||||||
|
LoadedAssemblies = new List<LoadedAssembly>();
|
||||||
|
LoadedPluginFolderAssemblies = new List<LoadedAssembly>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves all the loaded assemblies from the program directory
|
||||||
|
/// </summary>
|
||||||
|
public static void AddProgramAssemblies()
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Getting Assemblies loaded with Essentials");
|
||||||
|
// Get the loaded assembly filenames
|
||||||
|
var appDi = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix);
|
||||||
|
var assemblyFiles = appDi.GetFiles("*.dll");
|
||||||
|
|
||||||
|
Debug.Console(2, "Found {0} Assemblies", assemblyFiles.Length);
|
||||||
|
|
||||||
|
foreach (var fi in assemblyFiles)
|
||||||
|
{
|
||||||
|
string version = string.Empty;
|
||||||
|
Assembly assembly = null;
|
||||||
|
|
||||||
|
switch (fi.Name)
|
||||||
|
{
|
||||||
|
case ("PepperDashEssentials.dll"):
|
||||||
|
{
|
||||||
|
version = Global.AssemblyVersion;
|
||||||
|
assembly = Assembly.GetExecutingAssembly();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ("PepperDashEssentialsBase.dll"):
|
||||||
|
{
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ("PepperDash_Core.dll"):
|
||||||
|
{
|
||||||
|
version = PepperDash.Core.Debug.PepperDashCoreVersion;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadedAssemblies.Add(new LoadedAssembly(fi.Name, version, assembly));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Debug.Level > 1)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Loaded Assemblies:");
|
||||||
|
|
||||||
|
foreach (var assembly in LoadedAssemblies)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Assembly: {0}", assembly.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads an assembly via Reflection and adds it to the list of loaded assemblies
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName"></param>
|
||||||
|
static LoadedAssembly LoadAssembly(string filePath)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Attempting to load {0}", filePath);
|
||||||
|
var assembly = Assembly.LoadFrom(filePath);
|
||||||
|
if (assembly != null)
|
||||||
|
{
|
||||||
|
var assyVersion = GetAssemblyVersion(assembly);
|
||||||
|
|
||||||
|
var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly);
|
||||||
|
LoadedAssemblies.Add(loadedAssembly);
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version);
|
||||||
|
return loadedAssembly;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to load assembly: '{0}'", filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to get the assembly informational version and if not possible gets the version
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assembly"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static string GetAssemblyVersion(Assembly assembly)
|
||||||
|
{
|
||||||
|
var ver = assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
|
||||||
|
if (ver != null && ver.Length > 0)
|
||||||
|
{
|
||||||
|
// Get the AssemblyInformationalVersion
|
||||||
|
AssemblyInformationalVersionAttribute verAttribute = ver[0] as AssemblyInformationalVersionAttribute;
|
||||||
|
return verAttribute.InformationalVersion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get the AssemblyVersion
|
||||||
|
var version = assembly.GetName().Version;
|
||||||
|
var verStr = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision);
|
||||||
|
return verStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the filename matches an already loaded assembly file's name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filename"></param>
|
||||||
|
/// <returns>True if file already matches loaded assembly file.</returns>
|
||||||
|
public static bool CheckIfAssemblyLoaded(string name)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Checking if assembly: {0} is loaded...", name);
|
||||||
|
var loadedAssembly = LoadedAssemblies.FirstOrDefault(s => s.Name.Equals(name));
|
||||||
|
|
||||||
|
if (loadedAssembly != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Assembly already loaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Assembly not loaded.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by console command to report the currently loaded assemblies and versions
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
public static void ReportAssemblyVersions(string command)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Loaded Assemblies:");
|
||||||
|
foreach (var assembly in LoadedAssemblies)
|
||||||
|
{
|
||||||
|
Debug.Console(0, "{0} Version: {1}", assembly.Name, assembly.Version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves any .dll assemblies not already loaded from the plugins folder to loadedPlugins folder
|
||||||
|
/// </summary>
|
||||||
|
static void MoveDllAssemblies()
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Looking for .dll assemblies from plugins folder...");
|
||||||
|
|
||||||
|
var pluginDi = new DirectoryInfo(_pluginDirectory);
|
||||||
|
var pluginFiles = pluginDi.GetFiles("*.dll");
|
||||||
|
|
||||||
|
if (pluginFiles.Length > 0)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(_loadedPluginsDirectoryPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(_loadedPluginsDirectoryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pluginFile in pluginFiles)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Found .dll: {0}", pluginFile.Name);
|
||||||
|
|
||||||
|
if (!CheckIfAssemblyLoaded(pluginFile.Name))
|
||||||
|
{
|
||||||
|
string filePath = string.Empty;
|
||||||
|
|
||||||
|
filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + pluginFile.Name;
|
||||||
|
|
||||||
|
// Check if there is a previous file in the loadedPlugins directory and delete
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath);
|
||||||
|
File.Delete(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the file
|
||||||
|
File.Move(pluginFile.FullName, filePath);
|
||||||
|
Debug.Console(2, "Moved {0} to {1}", pluginFile.FullName, filePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", pluginFile.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Error with plugin file {0} . Exception: {1}", pluginFile.FullName, e);
|
||||||
|
continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, "Done with .dll assemblies");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unzips each .cplz archive into the temp directory and moves any unloaded files into loadedPlugins
|
||||||
|
/// </summary>
|
||||||
|
static void UnzipAndMoveCplzArchives()
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Looking for .cplz archives from plugins folder...");
|
||||||
|
var di = new DirectoryInfo(_pluginDirectory);
|
||||||
|
var zFiles = di.GetFiles("*.cplz");
|
||||||
|
|
||||||
|
if (zFiles.Length > 0)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(_loadedPluginsDirectoryPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(_loadedPluginsDirectoryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var zfi in zFiles)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(_tempDirectory);
|
||||||
|
var tempDi = new DirectoryInfo(_tempDirectory);
|
||||||
|
|
||||||
|
Debug.Console(0, "Found cplz: {0}. Unzipping into temp plugins directory", zfi.Name);
|
||||||
|
var result = CrestronZIP.Unzip(zfi.FullName, tempDi.FullName);
|
||||||
|
Debug.Console(0, "UnZip Result: {0}", result.ToString());
|
||||||
|
|
||||||
|
var tempFiles = tempDi.GetFiles("*.dll");
|
||||||
|
foreach (var tempFile in tempFiles)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!CheckIfAssemblyLoaded(tempFile.Name))
|
||||||
|
{
|
||||||
|
string filePath = string.Empty;
|
||||||
|
|
||||||
|
filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + tempFile.Name;
|
||||||
|
|
||||||
|
// Check if there is a previous file in the loadedPlugins directory and delete
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath);
|
||||||
|
File.Delete(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the file
|
||||||
|
File.Move(tempFile.FullName, filePath);
|
||||||
|
Debug.Console(2, "Moved {0} to {1}", tempFile.FullName, filePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", tempFile.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Assembly {0} is not a custom assembly. Exception: {1}", tempFile.FullName, e);
|
||||||
|
continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the .cplz and the temp directory
|
||||||
|
Directory.Delete(_tempDirectory, true);
|
||||||
|
zfi.Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, "Done with .cplz archives");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to load the assemblies from the loadedPlugins folder
|
||||||
|
/// </summary>
|
||||||
|
static void LoadPluginAssemblies()
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Loading assemblies from loadedPlugins folder...");
|
||||||
|
var pluginDi = new DirectoryInfo(_loadedPluginsDirectoryPath);
|
||||||
|
var pluginFiles = pluginDi.GetFiles("*.dll");
|
||||||
|
|
||||||
|
Debug.Console(2, "Found {0} plugin assemblies to load", pluginFiles.Length);
|
||||||
|
|
||||||
|
foreach (var pluginFile in pluginFiles)
|
||||||
|
{
|
||||||
|
var loadedAssembly = LoadAssembly(pluginFile.FullName);
|
||||||
|
|
||||||
|
LoadedPluginFolderAssemblies.Add(loadedAssembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, "All Plugins Loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Iterate the loaded assemblies and try to call the LoadPlugin method
|
||||||
|
/// </summary>
|
||||||
|
static void LoadCustomPluginTypes()
|
||||||
|
{
|
||||||
|
Debug.Console(0, "Loading Custom Plugin Types...");
|
||||||
|
foreach (var loadedAssembly in LoadedPluginFolderAssemblies)
|
||||||
|
{
|
||||||
|
// iteratate this assembly's classes, looking for "LoadPlugin()" methods
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var assy = loadedAssembly.Assembly;
|
||||||
|
var types = assy.GetTypes();
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (typeof(IPluginDeviceFactory).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
var plugin = (IPluginDeviceFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
|
||||||
|
LoadCustomPlugin(plugin, loadedAssembly);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
|
||||||
|
var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin"));
|
||||||
|
if (loadPlugin != null)
|
||||||
|
{
|
||||||
|
LoadCustomLegacyPlugin(type, loadPlugin, loadedAssembly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly. Exception: {1}", loadedAssembly.Name, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Error Loading Assembly: {0} Exception: (1) ", loadedAssembly.Name, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// plugin dll will be loaded. Any classes in plugin should have a static constructor
|
||||||
|
// that registers that class with the Core.DeviceFactory
|
||||||
|
Debug.Console(0, "Done Loading Custom Plugin Types.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin"></param>
|
||||||
|
static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly)
|
||||||
|
{
|
||||||
|
var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
|
||||||
|
|
||||||
|
if (!passed)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", plugin.MinimumEssentialsFrameworkVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading plugin: {0}", loadedAssembly.Name);
|
||||||
|
plugin.LoadTypeFactories();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a a custom plugin via the legacy method
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="loadPlugin"></param>
|
||||||
|
static void LoadCustomLegacyPlugin(CType type, MethodInfo loadPlugin, LoadedAssembly loadedAssembly)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "LoadPlugin method found in {0}", type.Name);
|
||||||
|
|
||||||
|
var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||||
|
|
||||||
|
var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion"));
|
||||||
|
if (minimumVersion != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "MinimumEssentialsFrameworkVersion found");
|
||||||
|
|
||||||
|
var minimumVersionString = minimumVersion.GetValue(null) as string;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(minimumVersionString))
|
||||||
|
{
|
||||||
|
var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString);
|
||||||
|
|
||||||
|
if (!passed)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading legacy plugin: {0}", loadedAssembly.Name);
|
||||||
|
loadPlugin.Invoke(null, null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads plugins
|
||||||
|
/// </summary>
|
||||||
|
public static void LoadPlugins()
|
||||||
|
{
|
||||||
|
if (Directory.Exists(_pluginDirectory))
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for plugins");
|
||||||
|
|
||||||
|
// Deal with any .dll files
|
||||||
|
MoveDllAssemblies();
|
||||||
|
|
||||||
|
// Deal with any .cplz files
|
||||||
|
UnzipAndMoveCplzArchives();
|
||||||
|
|
||||||
|
if(Directory.Exists(_loadedPluginsDirectoryPath)) {
|
||||||
|
// Load the assemblies from the loadedPlugins folder into the AppDomain
|
||||||
|
LoadPluginAssemblies();
|
||||||
|
|
||||||
|
// Load the types from any custom plugin assemblies
|
||||||
|
LoadCustomPluginTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an assembly loaded at runtime and it's associated metadata
|
||||||
|
/// </summary>
|
||||||
|
public class LoadedAssembly
|
||||||
|
{
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public string Version { get; private set; }
|
||||||
|
public Assembly Assembly { get; private set; }
|
||||||
|
|
||||||
|
public LoadedAssembly(string name, string version, Assembly assembly)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Version = version;
|
||||||
|
Assembly = assembly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
PepperDashEssentials/Properties/AssemblyInfo.cs
Normal file
10
PepperDashEssentials/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Crestron.SimplSharp.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyTitle("PepperDashEssentials")]
|
||||||
|
[assembly: System.Reflection.AssemblyCompany("PepperDash Technology Corp")]
|
||||||
|
[assembly: System.Reflection.AssemblyProduct("PepperDashEssentials")]
|
||||||
|
[assembly: System.Reflection.AssemblyCopyright("Copyright © PepperDash Technology Corp 2020")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersion("0.0.0.*")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersion("0.0.0-buildType-buildNumber")]
|
||||||
|
[assembly: Crestron.SimplSharp.Reflection.AssemblyInformationalVersion("0.0.0-buildType-buildNumber")]
|
||||||
12
PepperDashEssentials/Properties/AssemblyInfo.cs.orig
Normal file
12
PepperDashEssentials/Properties/AssemblyInfo.cs.orig
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: AssemblyTitle("PepperDashEssentials")]
|
||||||
|
[assembly: AssemblyCompany("PepperDash Technology Corp")]
|
||||||
|
[assembly: AssemblyProduct("PepperDashEssentials")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2017")]
|
||||||
|
<<<<<<< HEAD
|
||||||
|
[assembly: AssemblyVersion("1.1.8.*")]
|
||||||
|
=======
|
||||||
|
[assembly: AssemblyVersion("1.3.0.*")]
|
||||||
|
|
||||||
|
>>>>>>> feature/ecs-684
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ControlSystem>
|
<ControlSystem>
|
||||||
<Name>Test RMC3</Name>
|
<Name>Test RMC3</Name>
|
||||||
<Address>auto 192.168.1.40;username crestron</Address>
|
<Address>auto 192.168.1.40;username crestron</Address>
|
||||||
<ProgramSlot>Program01</ProgramSlot>
|
<ProgramSlot>Program01</ProgramSlot>
|
||||||
<Storage>Internal Flash</Storage>
|
<Storage>Internal Flash</Storage>
|
||||||
</ControlSystem>
|
</ControlSystem>
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
public class EssentialsDualDisplayRoomPropertiesConfig : EssentialsNDisplayRoomPropertiesConfig
|
public class EssentialsDualDisplayRoomPropertiesConfig : EssentialsNDisplayRoomPropertiesConfig
|
||||||
@@ -1,4 +1,12 @@
|
|||||||
using Newtonsoft.Json;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
@@ -1,377 +1,411 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Crestron.SimplSharp;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using System.Text;
|
||||||
using PepperDash.Core;
|
|
||||||
using PepperDash.Essentials.Core;
|
using Crestron.SimplSharp;
|
||||||
using PepperDash.Essentials.Core.Privacy;
|
using Newtonsoft.Json;
|
||||||
using Serilog.Events;
|
|
||||||
|
using PepperDash.Core;
|
||||||
namespace PepperDash.Essentials.Room.Config
|
using PepperDash.Essentials;
|
||||||
{
|
using PepperDash.Essentials.Core;
|
||||||
public class EssentialsRoomConfigHelper
|
using PepperDash.Essentials.Core.Config;
|
||||||
{
|
|
||||||
/// <summary>
|
namespace PepperDash.Essentials.Room.Config
|
||||||
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
|
{
|
||||||
/// Returns null if there is no emergency defined
|
public class EssentialsRoomConfigHelper
|
||||||
/// </summary>
|
{
|
||||||
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room)
|
/// <summary>
|
||||||
{
|
/// Returns a room object from this config data
|
||||||
// This emergency
|
/// </summary>
|
||||||
var emergency = props.Emergency;
|
/// <returns></returns>
|
||||||
if (emergency != null)
|
public static IKeyed GetRoomObject(DeviceConfig roomConfig)
|
||||||
{
|
{
|
||||||
//switch on emergency type here. Right now only contact and shutdown
|
var typeName = roomConfig.Type.ToLower();
|
||||||
var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room);
|
|
||||||
DeviceManager.AddDevice(e);
|
switch (typeName)
|
||||||
return e;
|
{
|
||||||
}
|
case "huddle" :
|
||||||
return null;
|
{
|
||||||
}
|
return new EssentialsHuddleSpaceRoom(roomConfig);
|
||||||
|
}
|
||||||
/// <summary>
|
case "huddlevtc1" :
|
||||||
///
|
{
|
||||||
/// </summary>
|
return new EssentialsHuddleVtc1Room(roomConfig);
|
||||||
/// <param name="props"></param>
|
}
|
||||||
/// <param name="room"></param>
|
case "ddvc01bridge" :
|
||||||
/// <returns></returns>
|
{
|
||||||
public static MicrophonePrivacyController GetMicrophonePrivacy(
|
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||||
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
}
|
||||||
{
|
case "dualdisplay" :
|
||||||
var microphonePrivacy = props.MicrophonePrivacy;
|
{
|
||||||
if (microphonePrivacy == null)
|
return new EssentialsDualDisplayRoom(roomConfig);
|
||||||
{
|
}
|
||||||
Debug.LogMessage(LogEventLevel.Information, "Cannot create microphone privacy with null properties");
|
case "combinedhuddlevtc1" :
|
||||||
return null;
|
{
|
||||||
}
|
return new EssentialsCombinedHuddleVtc1Room(roomConfig);
|
||||||
// Get the MicrophonePrivacy device from the device manager
|
}
|
||||||
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as MicrophonePrivacyController);
|
case "techroom" :
|
||||||
// Set this room as the IPrivacy device
|
{
|
||||||
if (mP == null)
|
return new EssentialsTechRoom(roomConfig);
|
||||||
{
|
}
|
||||||
Debug.LogMessage(LogEventLevel.Information, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
default :
|
||||||
return null;
|
{
|
||||||
}
|
return Core.DeviceFactory.GetDevice(roomConfig);
|
||||||
mP.SetPrivacyDevice(room);
|
}
|
||||||
|
}
|
||||||
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
}
|
||||||
|
|
||||||
if (behaviour == null)
|
/// <summary>
|
||||||
{
|
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
|
||||||
Debug.LogMessage(LogEventLevel.Information, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
/// Returns null if there is no emergency defined
|
||||||
return null;
|
/// </summary>
|
||||||
}
|
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room)
|
||||||
if (behaviour == "trackroomstate")
|
{
|
||||||
{
|
// This emergency
|
||||||
// Tie LED enable to room power state
|
var emergency = props.Emergency;
|
||||||
var essRoom = room as IEssentialsRoom;
|
if (emergency != null)
|
||||||
essRoom.OnFeedback.OutputChange += (o, a) =>
|
{
|
||||||
{
|
//switch on emergency type here. Right now only contact and shutdown
|
||||||
if (essRoom.OnFeedback.BoolValue)
|
var e = new EssentialsRoomEmergencyContactClosure(room.Key + "-emergency", props.Emergency, room);
|
||||||
mP.EnableLeds = true;
|
DeviceManager.AddDevice(e);
|
||||||
else
|
}
|
||||||
mP.EnableLeds = false;
|
return null;
|
||||||
};
|
}
|
||||||
|
|
||||||
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
/// <summary>
|
||||||
}
|
///
|
||||||
else if (behaviour == "trackcallstate")
|
/// </summary>
|
||||||
{
|
/// <param name="props"></param>
|
||||||
// Tie LED enable to room power state
|
/// <param name="room"></param>
|
||||||
var inCallRoom = room as IHasInCallFeedback;
|
/// <returns></returns>
|
||||||
inCallRoom.InCallFeedback.OutputChange += (o, a) =>
|
public static Core.Privacy.MicrophonePrivacyController GetMicrophonePrivacy(
|
||||||
{
|
EssentialsRoomPropertiesConfig props, IPrivacy room)
|
||||||
if (inCallRoom.InCallFeedback.BoolValue)
|
{
|
||||||
mP.EnableLeds = true;
|
var microphonePrivacy = props.MicrophonePrivacy;
|
||||||
else
|
if (microphonePrivacy == null)
|
||||||
mP.EnableLeds = false;
|
{
|
||||||
};
|
Debug.Console(0, "Cannot create microphone privacy with null properties");
|
||||||
|
return null;
|
||||||
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
}
|
||||||
}
|
// Get the MicrophonePrivacy device from the device manager
|
||||||
|
var mP = (DeviceManager.GetDeviceForKey(props.MicrophonePrivacy.DeviceKey) as
|
||||||
return mP;
|
Core.Privacy.MicrophonePrivacyController);
|
||||||
}
|
// Set this room as the IPrivacy device
|
||||||
|
if (mP == null)
|
||||||
}
|
{
|
||||||
|
Debug.Console(0, "ERROR: Selected device {0} is not MicrophonePrivacyController", props.MicrophonePrivacy.DeviceKey);
|
||||||
/// <summary>
|
return null;
|
||||||
///
|
}
|
||||||
/// </summary>
|
mP.SetPrivacyDevice(room);
|
||||||
public class EssentialsRoomPropertiesConfig
|
|
||||||
{
|
var behaviour = props.MicrophonePrivacy.Behaviour.ToLower();
|
||||||
[JsonProperty("addresses")]
|
|
||||||
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
if (behaviour == null)
|
||||||
|
{
|
||||||
[JsonProperty("description")]
|
Debug.Console(0, "WARNING: No behaviour defined for MicrophonePrivacyController");
|
||||||
public string Description { get; set; }
|
return null;
|
||||||
|
}
|
||||||
[JsonProperty("emergency")]
|
if (behaviour == "trackroomstate")
|
||||||
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
{
|
||||||
|
// Tie LED enable to room power state
|
||||||
[JsonProperty("help")]
|
var essRoom = room as IEssentialsRoom;
|
||||||
public EssentialsHelpPropertiesConfig Help { get; set; }
|
essRoom.OnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
[JsonProperty("helpMessage")]
|
if (essRoom.OnFeedback.BoolValue)
|
||||||
public string HelpMessage { get; set; }
|
mP.EnableLeds = true;
|
||||||
|
else
|
||||||
/// <summary>
|
mP.EnableLeds = false;
|
||||||
/// Read this value to get the help message. It checks for the old and new config format.
|
};
|
||||||
/// </summary>
|
|
||||||
public string HelpMessageForDisplay
|
mP.EnableLeds = essRoom.OnFeedback.BoolValue;
|
||||||
{
|
}
|
||||||
get
|
else if (behaviour == "trackcallstate")
|
||||||
{
|
{
|
||||||
if(Help != null && !string.IsNullOrEmpty(Help.Message))
|
// Tie LED enable to room power state
|
||||||
{
|
var inCallRoom = room as IHasInCallFeedback;
|
||||||
return Help.Message;
|
inCallRoom.InCallFeedback.OutputChange += (o, a) =>
|
||||||
}
|
{
|
||||||
else
|
if (inCallRoom.InCallFeedback.BoolValue)
|
||||||
{
|
mP.EnableLeds = true;
|
||||||
return HelpMessage;
|
else
|
||||||
}
|
mP.EnableLeds = false;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
mP.EnableLeds = inCallRoom.InCallFeedback.BoolValue;
|
||||||
[JsonProperty("environment")]
|
}
|
||||||
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
|
||||||
|
return mP;
|
||||||
[JsonProperty("logo")]
|
}
|
||||||
public EssentialsLogoPropertiesConfig LogoLight { get; set; }
|
|
||||||
|
}
|
||||||
[JsonProperty("logoDark")]
|
|
||||||
public EssentialsLogoPropertiesConfig LogoDark { get; set; }
|
/// <summary>
|
||||||
|
///
|
||||||
[JsonProperty("microphonePrivacy")]
|
/// </summary>
|
||||||
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
public class EssentialsRoomPropertiesConfig
|
||||||
|
{
|
||||||
[JsonProperty("occupancy")]
|
[JsonProperty("addresses")]
|
||||||
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
||||||
|
|
||||||
[JsonProperty("oneButtonMeeting")]
|
[JsonProperty("description")]
|
||||||
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
[JsonProperty("shutdownVacancySeconds")]
|
[JsonProperty("emergency")]
|
||||||
public int ShutdownVacancySeconds { get; set; }
|
public EssentialsRoomEmergencyConfig Emergency { get; set; }
|
||||||
|
|
||||||
[JsonProperty("shutdownPromptSeconds")]
|
[JsonProperty("help")]
|
||||||
public int ShutdownPromptSeconds { get; set; }
|
public EssentialsHelpPropertiesConfig Help { get; set; }
|
||||||
|
|
||||||
[JsonProperty("tech")]
|
[JsonProperty("helpMessage")]
|
||||||
public EssentialsRoomTechConfig Tech { get; set; }
|
public string HelpMessage { get; set; }
|
||||||
|
|
||||||
[JsonProperty("volumes")]
|
/// <summary>
|
||||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
/// Read this value to get the help message. It checks for the old and new config format.
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("fusion")]
|
public string HelpMessageForDisplay
|
||||||
public EssentialsRoomFusionConfig Fusion { get; set; }
|
{
|
||||||
|
get
|
||||||
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)]
|
{
|
||||||
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
|
if(Help != null && !string.IsNullOrEmpty(Help.Message))
|
||||||
|
{
|
||||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
return Help.Message;
|
||||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
}
|
||||||
|
else
|
||||||
/// <summary>
|
{
|
||||||
/// Indicates if this room represents a combination of other rooms
|
return HelpMessage;
|
||||||
/// </summary>
|
}
|
||||||
[JsonProperty("isRoomCombinationScenario")]
|
}
|
||||||
public bool IsRoomCombinationScenario { get; set; }
|
}
|
||||||
|
|
||||||
public EssentialsRoomPropertiesConfig()
|
[JsonProperty("environment")]
|
||||||
{
|
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
|
||||||
LogoLight = new EssentialsLogoPropertiesConfig();
|
|
||||||
LogoDark = new EssentialsLogoPropertiesConfig();
|
[JsonProperty("logo")]
|
||||||
}
|
public EssentialsLogoPropertiesConfig LogoLight { get; set; }
|
||||||
}
|
|
||||||
|
[JsonProperty("logoDark")]
|
||||||
public class EssentialsRoomUiBehaviorConfig
|
public EssentialsLogoPropertiesConfig LogoDark { get; set; }
|
||||||
{
|
|
||||||
[JsonProperty("disableActivityButtonsWhileWarmingCooling")]
|
[JsonProperty("microphonePrivacy")]
|
||||||
public bool DisableActivityButtonsWhileWarmingCooling { get; set; }
|
public EssentialsRoomMicrophonePrivacyConfig MicrophonePrivacy { get; set; }
|
||||||
}
|
|
||||||
|
[JsonProperty("occupancy")]
|
||||||
public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig
|
public EssentialsRoomOccSensorConfig Occupancy { get; set; }
|
||||||
{
|
|
||||||
[JsonProperty("defaultAudioKey")]
|
[JsonProperty("oneButtonMeeting")]
|
||||||
public string DefaultAudioKey { get; set; }
|
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
||||||
[JsonProperty("sourceListKey")]
|
|
||||||
public string SourceListKey { get; set; }
|
[JsonProperty("shutdownVacancySeconds")]
|
||||||
[JsonProperty("destinationListKey")]
|
public int ShutdownVacancySeconds { get; set; }
|
||||||
public string DestinationListKey { get; set; }
|
|
||||||
[JsonProperty("audioControlPointListKey")]
|
[JsonProperty("shutdownPromptSeconds")]
|
||||||
public string AudioControlPointListKey { get; set; }
|
public int ShutdownPromptSeconds { get; set; }
|
||||||
[JsonProperty("cameraListKey")]
|
|
||||||
public string CameraListKey { get; set; }
|
[JsonProperty("tech")]
|
||||||
|
public EssentialsRoomTechConfig Tech { get; set; }
|
||||||
|
|
||||||
[JsonProperty("defaultSourceItem")]
|
[JsonProperty("volumes")]
|
||||||
public string DefaultSourceItem { get; set; }
|
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// Indicates if the room supports advanced sharing
|
[JsonProperty("fusion")]
|
||||||
/// </summary>
|
public EssentialsRoomFusionConfig Fusion { get; set; }
|
||||||
[JsonProperty("supportsAdvancedSharing")]
|
|
||||||
public bool SupportsAdvancedSharing { get; set; }
|
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)]
|
||||||
/// <summary>
|
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
|
||||||
/// Indicates if non-tech users can change the share mode
|
|
||||||
/// </summary>
|
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||||
[JsonProperty("userCanChangeShareMode")]
|
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||||
public bool UserCanChangeShareMode { get; set; }
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates if this room represents a combination of other rooms
|
||||||
[JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
|
/// </summary>
|
||||||
public string MatrixRoutingKey { get; set; }
|
[JsonProperty("isRoomCombinationScenario")]
|
||||||
}
|
public bool IsRoomCombinationScenario { get; set; }
|
||||||
|
|
||||||
public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig
|
public EssentialsRoomPropertiesConfig()
|
||||||
{
|
{
|
||||||
[JsonProperty("videoCodecKey")]
|
LogoLight = new EssentialsLogoPropertiesConfig();
|
||||||
public string VideoCodecKey { get; set; }
|
LogoDark = new EssentialsLogoPropertiesConfig();
|
||||||
[JsonProperty("audioCodecKey")]
|
}
|
||||||
public string AudioCodecKey { get; set; }
|
}
|
||||||
|
|
||||||
}
|
public class EssentialsRoomUiBehaviorConfig
|
||||||
|
{
|
||||||
public class EssentialsEnvironmentPropertiesConfig
|
[JsonProperty("disableActivityButtonsWhileWarmingCooling")]
|
||||||
{
|
public bool DisableActivityButtonsWhileWarmingCooling { get; set; }
|
||||||
public bool Enabled { get; set; }
|
}
|
||||||
|
|
||||||
[JsonProperty("deviceKeys")]
|
public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig
|
||||||
public List<string> DeviceKeys { get; set; }
|
{
|
||||||
|
[JsonProperty("defaultAudioKey")]
|
||||||
public EssentialsEnvironmentPropertiesConfig()
|
public string DefaultAudioKey { get; set; }
|
||||||
{
|
[JsonProperty("sourceListKey")]
|
||||||
DeviceKeys = new List<string>();
|
public string SourceListKey { get; set; }
|
||||||
}
|
[JsonProperty("destinationListKey")]
|
||||||
|
public string DestinationListKey { get; set; }
|
||||||
}
|
[JsonProperty("defaultSourceItem")]
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
public class EssentialsRoomFusionConfig
|
/// <summary>
|
||||||
{
|
/// Indicates if the room supports advanced sharing
|
||||||
public uint IpIdInt
|
/// </summary>
|
||||||
{
|
[JsonProperty("supportsAdvancedSharing")]
|
||||||
get
|
public bool SupportsAdvancedSharing { get; set; }
|
||||||
{
|
/// <summary>
|
||||||
try
|
/// Indicates if non-tech users can change the share mode
|
||||||
{
|
/// </summary>
|
||||||
return Convert.ToUInt32(IpId, 16);
|
[JsonProperty("userCanChangeShareMode")]
|
||||||
}
|
public bool UserCanChangeShareMode { get; set; }
|
||||||
catch (Exception)
|
}
|
||||||
{
|
|
||||||
throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
|
public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig
|
||||||
}
|
{
|
||||||
|
[JsonProperty("videoCodecKey")]
|
||||||
}
|
public string VideoCodecKey { get; set; }
|
||||||
}
|
[JsonProperty("audioCodecKey")]
|
||||||
|
public string AudioCodecKey { get; set; }
|
||||||
[JsonProperty("ipId")]
|
}
|
||||||
public string IpId { get; set; }
|
|
||||||
|
public class EssentialsEnvironmentPropertiesConfig
|
||||||
[JsonProperty("joinMapKey")]
|
{
|
||||||
public string JoinMapKey { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
}
|
[JsonProperty("deviceKeys")]
|
||||||
|
public List<string> DeviceKeys { get; set; }
|
||||||
public class EssentialsRoomMicrophonePrivacyConfig
|
|
||||||
{
|
public EssentialsEnvironmentPropertiesConfig()
|
||||||
[JsonProperty("deviceKey")]
|
{
|
||||||
public string DeviceKey { get; set; }
|
DeviceKeys = new List<string>();
|
||||||
|
}
|
||||||
[JsonProperty("behaviour")]
|
|
||||||
public string Behaviour { get; set; }
|
}
|
||||||
}
|
|
||||||
|
public class EssentialsRoomFusionConfig
|
||||||
/// <summary>
|
{
|
||||||
/// Properties for the help text box
|
public uint IpIdInt
|
||||||
/// </summary>
|
{
|
||||||
public class EssentialsHelpPropertiesConfig
|
get
|
||||||
{
|
{
|
||||||
[JsonProperty("message")]
|
try
|
||||||
public string Message { get; set; }
|
{
|
||||||
|
return Convert.ToUInt32(IpId, 16);
|
||||||
[JsonProperty("showCallButton")]
|
}
|
||||||
public bool ShowCallButton { get; set; }
|
catch (Exception)
|
||||||
|
{
|
||||||
/// <summary>
|
throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
|
||||||
/// Defaults to "Call Help Desk"
|
}
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("callButtonText")]
|
}
|
||||||
public string CallButtonText { get; set; }
|
}
|
||||||
|
|
||||||
public EssentialsHelpPropertiesConfig()
|
[JsonProperty("ipId")]
|
||||||
{
|
public string IpId { get; set; }
|
||||||
CallButtonText = "Call Help Desk";
|
|
||||||
}
|
[JsonProperty("joinMapKey")]
|
||||||
}
|
public string JoinMapKey { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
}
|
||||||
///
|
|
||||||
/// </summary>
|
public class EssentialsRoomMicrophonePrivacyConfig
|
||||||
public class EssentialsOneButtonMeetingPropertiesConfig
|
{
|
||||||
{
|
[JsonProperty("deviceKey")]
|
||||||
[JsonProperty("enable")]
|
public string DeviceKey { get; set; }
|
||||||
public bool Enable { get; set; }
|
|
||||||
}
|
[JsonProperty("behaviour")]
|
||||||
|
public string Behaviour { get; set; }
|
||||||
public class EssentialsRoomAddressPropertiesConfig
|
}
|
||||||
{
|
|
||||||
[JsonProperty("phoneNumber")]
|
/// <summary>
|
||||||
public string PhoneNumber { get; set; }
|
/// Properties for the help text box
|
||||||
|
/// </summary>
|
||||||
[JsonProperty("sipAddress")]
|
public class EssentialsHelpPropertiesConfig
|
||||||
public string SipAddress { get; set; }
|
{
|
||||||
}
|
[JsonProperty("message")]
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
[JsonProperty("showCallButton")]
|
||||||
/// Properties for the room's logo on panels
|
public bool ShowCallButton { get; set; }
|
||||||
/// </summary>
|
|
||||||
public class EssentialsLogoPropertiesConfig
|
/// <summary>
|
||||||
{
|
/// Defaults to "Call Help Desk"
|
||||||
[JsonProperty("type")]
|
/// </summary>
|
||||||
public string Type { get; set; }
|
[JsonProperty("callButtonText")]
|
||||||
|
public string CallButtonText { get; set; }
|
||||||
[JsonProperty("url")]
|
|
||||||
public string Url { get; set; }
|
public EssentialsHelpPropertiesConfig()
|
||||||
/// <summary>
|
{
|
||||||
/// Gets either the custom URL, a local-to-processor URL, or null if it's a default logo
|
CallButtonText = "Call Help Desk";
|
||||||
/// </summary>
|
}
|
||||||
public string GetLogoUrlLight()
|
}
|
||||||
{
|
|
||||||
if (Type == "url")
|
/// <summary>
|
||||||
return Url;
|
///
|
||||||
if (Type == "system")
|
/// </summary>
|
||||||
return string.Format("http://{0}:8080/logo.png",
|
public class EssentialsOneButtonMeetingPropertiesConfig
|
||||||
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
{
|
||||||
return null;
|
[JsonProperty("enable")]
|
||||||
}
|
public bool Enable { get; set; }
|
||||||
|
}
|
||||||
public string GetLogoUrlDark()
|
|
||||||
{
|
public class EssentialsRoomAddressPropertiesConfig
|
||||||
if (Type == "url")
|
{
|
||||||
return Url;
|
[JsonProperty("phoneNumber")]
|
||||||
if (Type == "system")
|
public string PhoneNumber { get; set; }
|
||||||
return string.Format("http://{0}:8080/logo-dark.png",
|
|
||||||
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
[JsonProperty("sipAddress")]
|
||||||
return null;
|
public string SipAddress { get; set; }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents occupancy sensor(s) setup for a room
|
/// Properties for the room's logo on panels
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EssentialsRoomOccSensorConfig
|
public class EssentialsLogoPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("deviceKey")]
|
[JsonProperty("type")]
|
||||||
public string DeviceKey { get; set; }
|
public string Type { get; set; }
|
||||||
|
|
||||||
[JsonProperty("timeoutMinutes")]
|
[JsonProperty("url")]
|
||||||
public int TimeoutMinutes { get; set; }
|
public string Url { get; set; }
|
||||||
}
|
/// <summary>
|
||||||
|
/// Gets either the custom URL, a local-to-processor URL, or null if it's a default logo
|
||||||
public class EssentialsRoomTechConfig
|
/// </summary>
|
||||||
{
|
public string GetLogoUrlLight()
|
||||||
[JsonProperty("password")]
|
{
|
||||||
public string Password { get; set; }
|
if (Type == "url")
|
||||||
}
|
return Url;
|
||||||
|
if (Type == "system")
|
||||||
|
return string.Format("http://{0}:8080/logo.png",
|
||||||
|
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetLogoUrlDark()
|
||||||
|
{
|
||||||
|
if (Type == "url")
|
||||||
|
return Url;
|
||||||
|
if (Type == "system")
|
||||||
|
return string.Format("http://{0}:8080/logo-dark.png",
|
||||||
|
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents occupancy sensor(s) setup for a room
|
||||||
|
/// </summary>
|
||||||
|
public class EssentialsRoomOccSensorConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("deviceKey")]
|
||||||
|
public string DeviceKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeoutMinutes")]
|
||||||
|
public int TimeoutMinutes { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EssentialsRoomTechConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("password")]
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
namespace PepperDash.Essentials.Room.Config
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -16,7 +22,7 @@
|
|||||||
public class EssentialsRoomEmergencyTriggerConfig
|
public class EssentialsRoomEmergencyTriggerConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// contact,versiport
|
/// contact,
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Essentials.Room.Config;
|
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Room.Config
|
namespace PepperDash.Essentials.Room.Config
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
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.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Room
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
|
||||||
|
{
|
||||||
|
IEssentialsRoom Room;
|
||||||
|
string Behavior;
|
||||||
|
bool TriggerOnClose;
|
||||||
|
|
||||||
|
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
|
||||||
|
base(key)
|
||||||
|
{
|
||||||
|
Room = room;
|
||||||
|
var cs = Global.ControlSystem;
|
||||||
|
|
||||||
|
if (config.Trigger.Type.Equals("contact", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
var portNum = (uint)config.Trigger.Number;
|
||||||
|
if (portNum <= cs.NumberOfDigitalInputPorts)
|
||||||
|
{
|
||||||
|
cs.DigitalInputPorts[portNum].Register();
|
||||||
|
cs.DigitalInputPorts[portNum].StateChange += EsentialsRoomEmergencyContactClosure_StateChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior = config.Behavior;
|
||||||
|
TriggerOnClose = config.Trigger.TriggerOnClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsentialsRoomEmergencyContactClosure_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.State && TriggerOnClose || !args.State && !TriggerOnClose)
|
||||||
|
RunEmergencyBehavior();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public void RunEmergencyBehavior()
|
||||||
|
{
|
||||||
|
if (Behavior.Equals("shutdown"))
|
||||||
|
Room.Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,821 @@
|
|||||||
|
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;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsCombinedHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
|
||||||
|
{
|
||||||
|
private bool _codecExternalSourceChange;
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Make this more specific
|
||||||
|
///// </summary>
|
||||||
|
//public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
|
||||||
|
var displays = Displays.OfType<DisplayBase>().ToList();
|
||||||
|
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& displays.Count > 0;
|
||||||
|
//&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () => Displays.OfType<TwoWayDisplayBase>().Any((d) => d.IsWarmingUpFeedback.BoolValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () => Displays.OfType<TwoWayDisplayBase>().Any((d) => d.IsCoolingDownFeedback.BoolValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
|
private List<IRoutingSinkWithSwitching> Displays;
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public AudioCodecBase AudioCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||||
|
/// tag to device.
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
|
||||||
|
var vc = VideoCodec as IHasExternalSourceSwitching;
|
||||||
|
if (vc != null && !_codecExternalSourceChange)
|
||||||
|
{
|
||||||
|
vc.SetSelectedSource(CurrentSourceInfoKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
_codecExternalSourceChange = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||||
|
|
||||||
|
public EssentialsCombinedHuddleVtc1Room(DeviceConfig config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
|
||||||
|
(config.Properties.ToString());
|
||||||
|
|
||||||
|
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||||
|
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||||
|
|
||||||
|
|
||||||
|
if (VideoCodec == null)
|
||||||
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
|
||||||
|
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||||
|
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||||
|
if (AudioCodec == null)
|
||||||
|
Debug.Console(0, this, "No Audio Codec Found");
|
||||||
|
|
||||||
|
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
|
||||||
|
|
||||||
|
Displays = new List<IRoutingSinkWithSwitching>();
|
||||||
|
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error building room: \n{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||||
|
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
|
||||||
|
// Combines call feedback from both codecs if available
|
||||||
|
InCallFeedback = new BoolFeedback(() =>
|
||||||
|
{
|
||||||
|
bool inAudioCall = false;
|
||||||
|
bool inVideoCall = false;
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
inAudioCall = AudioCodec.IsInCall;
|
||||||
|
|
||||||
|
if (VideoCodec != null)
|
||||||
|
inVideoCall = VideoCodec.IsInCall;
|
||||||
|
|
||||||
|
if (inAudioCall || inVideoCall)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
SetupDisplays();
|
||||||
|
|
||||||
|
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
|
||||||
|
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||||
|
|
||||||
|
// Get emergency object, if any
|
||||||
|
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||||
|
|
||||||
|
|
||||||
|
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SetSourceListKey();
|
||||||
|
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Error Initializing Room: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupDisplays()
|
||||||
|
{
|
||||||
|
//DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
|
var destinationList = ConfigReader.ConfigObject.DestinationLists[PropertiesConfig.DestinationListKey];
|
||||||
|
|
||||||
|
foreach (var destination in destinationList)
|
||||||
|
{
|
||||||
|
var dest = destination.Value.SinkDevice as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
|
if (dest != null)
|
||||||
|
{
|
||||||
|
Displays.Add(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
var display = dest as DisplayBase;
|
||||||
|
if (display != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
var dispTwoWay = display as IHasPowerControlWithFeedback;
|
||||||
|
if (dispTwoWay != null)
|
||||||
|
{
|
||||||
|
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
//if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
// CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
display.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
display.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetSourceListKey()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||||
|
{
|
||||||
|
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSourceListKey(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCodecExternalSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CustomSetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
|
||||||
|
|
||||||
|
if (newPropertiesConfig != null)
|
||||||
|
PropertiesConfig = newPropertiesConfig;
|
||||||
|
|
||||||
|
ConfigWriter.UpdateRoomConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
// Add Occupancy object from config
|
||||||
|
if (PropertiesConfig.Occupancy != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
|
||||||
|
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||||
|
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||||
|
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||||
|
|
||||||
|
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||||
|
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||||
|
|
||||||
|
return base.CustomActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
|
||||||
|
SetDefaultLevels();
|
||||||
|
|
||||||
|
RunDefaultPresentRoute();
|
||||||
|
|
||||||
|
CrestronEnvironment.Sleep(1000);
|
||||||
|
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||||
|
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
VideoCodec.StopSharing();
|
||||||
|
VideoCodec.StandbyActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public override bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
RunRouteAction(DefaultCodecRouteString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunRouteActionCodec(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
_codecExternalSourceChange = true;
|
||||||
|
RunRouteAction(routeKey, sourceListKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="souceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sourceListKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "No sourceListKey present. RunRouteAction assumes default source list.");
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="souceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sourceListKey))
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, successCallback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
// try to prevent multiple simultaneous selections
|
||||||
|
SourceSelectLock.TryEnter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if this can be moved into common, base-class method -------------
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
//else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
// volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volDev != CurrentVolumeControls)
|
||||||
|
{
|
||||||
|
// zero the volume on the device we are leaving.
|
||||||
|
// Set the volume to default on device we are entering
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
|
||||||
|
vd.SetVolume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||||
|
vd.SetVolume(vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
if (OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
|
||||||
|
VideoCodec.StandbyDeactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
VideoCodec.StandbyDeactivate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceSelectLock.Leave();
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
foreach (var display in Displays)
|
||||||
|
{
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = display.Key,
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSink dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSink;
|
||||||
|
//else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
// dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IHasPowerControl)
|
||||||
|
(dest as IHasPowerControl).PowerOff();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
if (vc != null)
|
||||||
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public override void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||||
|
/// </summary>
|
||||||
|
private void SetCodecExternalSources()
|
||||||
|
{
|
||||||
|
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||||
|
|
||||||
|
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get the tie line that the external switcher is connected to
|
||||||
|
string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
|
||||||
|
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
|
||||||
|
|
||||||
|
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||||
|
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
|
||||||
|
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||||
|
|
||||||
|
foreach (var kvp in srcList)
|
||||||
|
{
|
||||||
|
var srcConfig = kvp.Value;
|
||||||
|
|
||||||
|
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||||
|
{
|
||||||
|
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||||
|
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCodecBranding()
|
||||||
|
{
|
||||||
|
var vcWithBranding = VideoCodec as IHasBranding;
|
||||||
|
|
||||||
|
if (vcWithBranding == null) return;
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Setting Codec Branding");
|
||||||
|
vcWithBranding.InitializeBranding(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPrivacy Members
|
||||||
|
|
||||||
|
|
||||||
|
public void PrivacyModeOff()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeOn()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeToggle()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
673
PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
Normal file
673
PepperDashEssentials/Room/Types/EssentialsDualDisplayRoom.cs
Normal file
@@ -0,0 +1,673 @@
|
|||||||
|
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;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsDualDisplayRoom : EssentialsNDisplayRoomBase, IHasCurrentVolumeControls,
|
||||||
|
IRunRouteAction, IPrivacy, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasInCallFeedback
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
|
||||||
|
public EssentialsDualDisplayRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching LeftDisplay { get; private set; }
|
||||||
|
public IRoutingSinkWithSwitching RightDisplay { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var leftDisp = LeftDisplay as DisplayBase;
|
||||||
|
var rightDisp = RightDisplay as DisplayBase;
|
||||||
|
var val = leftDisp != null && leftDisp.CurrentSourceInfo != null
|
||||||
|
&& leftDisp.CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& rightDisp != null && rightDisp.CurrentSourceInfo != null
|
||||||
|
&& rightDisp.CurrentSourceInfo.Type == eSourceListItemType.Route;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var leftDisp = LeftDisplay as DisplayBase;
|
||||||
|
var rightDisp = RightDisplay as DisplayBase;
|
||||||
|
if (leftDisp != null && RightDisplay != null)
|
||||||
|
return leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var leftDisp = LeftDisplay as DisplayBase;
|
||||||
|
var rightDisp = RightDisplay as DisplayBase;
|
||||||
|
if (leftDisp != null && RightDisplay != null)
|
||||||
|
return leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public AudioCodecBase AudioCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||||
|
/// tag to device.
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||||
|
|
||||||
|
public EssentialsDualDisplayRoom(DeviceConfig config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsDualDisplayRoomPropertiesConfig>
|
||||||
|
(config.Properties.ToString());
|
||||||
|
|
||||||
|
var leftDisp = PropertiesConfig.Displays[eSourceListItemDestinationTypes.leftDisplay];
|
||||||
|
if (leftDisp != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(leftDisp.Key))
|
||||||
|
{
|
||||||
|
LeftDisplay = DeviceManager.GetDeviceForKey(leftDisp.Key) as IRoutingSinkWithSwitching;
|
||||||
|
Displays.Add(eSourceListItemDestinationTypes.leftDisplay, LeftDisplay);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, this, "Unable to get LeftDisplay for Room");
|
||||||
|
}
|
||||||
|
|
||||||
|
var rightDisp = PropertiesConfig.Displays[eSourceListItemDestinationTypes.rightDisplay];
|
||||||
|
if (rightDisp != null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(rightDisp.Key))
|
||||||
|
{
|
||||||
|
LeftDisplay = DeviceManager.GetDeviceForKey(rightDisp.Key) as IRoutingSinkWithSwitching;
|
||||||
|
Displays.Add(eSourceListItemDestinationTypes.rightDisplay, RightDisplay);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Debug.Console(0, this, "Unable to get LeftDisplay for Room");
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||||
|
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||||
|
if (VideoCodec == null)
|
||||||
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
|
||||||
|
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||||
|
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||||
|
if (AudioCodec == null)
|
||||||
|
Debug.Console(0, this, "No Audio Codec Found");
|
||||||
|
|
||||||
|
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
|
||||||
|
|
||||||
|
InitializeRoom();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error building room \n{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeRoom()
|
||||||
|
{
|
||||||
|
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||||
|
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
|
||||||
|
var leftDisp = LeftDisplay as DisplayBase;
|
||||||
|
if (leftDisp != null)
|
||||||
|
InitializeDisplay(leftDisp);
|
||||||
|
|
||||||
|
var rightDisp = RightDisplay as DisplayBase;
|
||||||
|
if (rightDisp != null)
|
||||||
|
InitializeDisplay(rightDisp);
|
||||||
|
|
||||||
|
// Get Microphone Privacy object, if any
|
||||||
|
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||||
|
|
||||||
|
// Get emergency object, if any
|
||||||
|
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||||
|
|
||||||
|
// Combines call feedback from both codecs if available
|
||||||
|
InCallFeedback = new BoolFeedback(() =>
|
||||||
|
{
|
||||||
|
bool inAudioCall = false;
|
||||||
|
bool inVideoCall = false;
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
inAudioCall = AudioCodec.IsInCall;
|
||||||
|
|
||||||
|
if (VideoCodec != null)
|
||||||
|
inVideoCall = VideoCodec.IsInCall;
|
||||||
|
|
||||||
|
if (inAudioCall || inVideoCall)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SetSourceListKey();
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetSourceListKey()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||||
|
{
|
||||||
|
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSourceListKey(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeDisplay(DisplayBase disp)
|
||||||
|
{
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||||
|
if (dispTwoWay != null)
|
||||||
|
{
|
||||||
|
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
disp.CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CustomSetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsDualDisplayRoomPropertiesConfig>(config.Properties.ToString());
|
||||||
|
|
||||||
|
if (newPropertiesConfig != null)
|
||||||
|
PropertiesConfig = newPropertiesConfig;
|
||||||
|
|
||||||
|
ConfigWriter.UpdateRoomConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
// Add Occupancy object from config
|
||||||
|
if (PropertiesConfig.Occupancy != null)
|
||||||
|
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||||
|
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||||
|
|
||||||
|
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||||
|
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||||
|
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||||
|
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||||
|
|
||||||
|
return base.CustomActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
|
||||||
|
SetDefaultLevels();
|
||||||
|
|
||||||
|
RunDefaultPresentRoute();
|
||||||
|
|
||||||
|
CrestronEnvironment.Sleep(1000);
|
||||||
|
|
||||||
|
RunRouteAction("roomOff", SourceListKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public override bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem, SourceListKey);
|
||||||
|
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
RunRouteAction(DefaultCodecRouteString, SourceListKey);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, sourceListKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
// try to prevent multiple simultaneous selections
|
||||||
|
SourceSelectLock.TryEnter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(sourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", sourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
// CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route, item, routeKey);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if this can be moved into common, base-class method -------------
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volDev != CurrentVolumeControls)
|
||||||
|
{
|
||||||
|
// zero the volume on the device we are leaving.
|
||||||
|
// Set the volume to default on device we are entering
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
|
||||||
|
vd.SetVolume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||||
|
vd.SetVolume(vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
LeftDisplay.CurrentSourceInfoKey = routeKey;
|
||||||
|
LeftDisplay.CurrentSourceInfo = null;
|
||||||
|
RightDisplay.CurrentSourceInfoKey = routeKey;
|
||||||
|
RightDisplay.CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
//else if (item.SourceKey != null)
|
||||||
|
//{
|
||||||
|
// if(item.RouteList
|
||||||
|
// CurrentSourceInfoKey = routeKey;
|
||||||
|
// CurrentSourceInfo = item;
|
||||||
|
//}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceSelectLock.Leave();
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo, sourceItem, sourceItemKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route, sourceItem, sourceItemKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||||
|
{
|
||||||
|
IRoutingSink dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||||
|
else if (route.DestinationKey.Equals(LeftDisplay.Key, StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = LeftDisplay;
|
||||||
|
else if (route.DestinationKey.Equals(RightDisplay.Key, StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = RightDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (dest is IHasPowerControl)
|
||||||
|
(dest as IHasPowerControl).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
|
||||||
|
dest.CurrentSourceInfoKey = sourceItemKey;
|
||||||
|
dest.CurrentSourceInfo = sourceItem;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
if (vc != null)
|
||||||
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public override void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey, SourceListKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is IEssentialsHuddleSpaceRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as IEssentialsHuddleSpaceRoom).SourceListKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPrivacy Members
|
||||||
|
|
||||||
|
|
||||||
|
public void PrivacyModeOff()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeOn()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeToggle()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
564
PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs
Normal file
564
PepperDashEssentials/Room/Types/EssentialsHuddleSpaceRoom.cs
Normal file
@@ -0,0 +1,564 @@
|
|||||||
|
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;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IEssentialsHuddleSpaceRoom
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null;
|
||||||
|
//&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IRoutingSink DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler( _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
|
|
||||||
|
public EssentialsHuddleSpaceRoom(DeviceConfig config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
|
||||||
|
(config.Properties.ToString());
|
||||||
|
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
|
|
||||||
|
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
|
InitializeRoom();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error building room: \n{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeRoom()
|
||||||
|
{
|
||||||
|
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||||
|
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||||
|
if (dispTwoWay != null)
|
||||||
|
{
|
||||||
|
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupEnvironmentalControlDevices();
|
||||||
|
|
||||||
|
SetSourceListKey();
|
||||||
|
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupEnvironmentalControlDevices()
|
||||||
|
{
|
||||||
|
if (PropertiesConfig.Environment != null)
|
||||||
|
{
|
||||||
|
if (PropertiesConfig.Environment.Enabled)
|
||||||
|
{
|
||||||
|
foreach (var d in PropertiesConfig.Environment.DeviceKeys)
|
||||||
|
{
|
||||||
|
var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
|
||||||
|
EnvironmentalControlDevices.Add(envDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetSourceListKey()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||||
|
{
|
||||||
|
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSourceListKey(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CustomSetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||||
|
|
||||||
|
if (newPropertiesConfig != null)
|
||||||
|
PropertiesConfig = newPropertiesConfig;
|
||||||
|
|
||||||
|
ConfigWriter.UpdateRoomConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
|
||||||
|
RunDefaultPresentRoute();
|
||||||
|
|
||||||
|
CrestronEnvironment.Sleep(1000);
|
||||||
|
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||||
|
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any
|
||||||
|
/// </summary>
|
||||||
|
public override bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Unable to run default present route, DefaultSourceItem is null.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
// Add Occupancy object from config
|
||||||
|
if (PropertiesConfig.Occupancy != null)
|
||||||
|
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||||
|
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||||
|
|
||||||
|
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||||
|
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||||
|
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||||
|
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||||
|
|
||||||
|
return base.CustomActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="souceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="souceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sourceListKey))
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, successCallback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if(dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = dict[routeKey];
|
||||||
|
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||||
|
// item.SourceKey, item.RouteList.Count);
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lastSource != null && lastSource is IUsageTracking)
|
||||||
|
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
|
||||||
|
//var tempAudio = new SourceRouteListItem
|
||||||
|
//{
|
||||||
|
// DestinationKey = "$defaultAudio",
|
||||||
|
// SourceKey = route.SourceKey,
|
||||||
|
// Type = eRoutingSignalType.Audio
|
||||||
|
//};
|
||||||
|
//DoRoute(tempAudio);
|
||||||
|
//continue; -- not sure why this was here
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
if (item.SourceDevice is IUsageTracking)
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volDev != CurrentVolumeControls)
|
||||||
|
{
|
||||||
|
// zero the volume on the device we are leaving.
|
||||||
|
// Set the volume to default on device we are entering
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
|
||||||
|
vd.SetVolume(0);
|
||||||
|
}
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||||
|
vd.SetVolume(vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
// And finally, set the "control". This will trigger event
|
||||||
|
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public override void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
if (vc != null)
|
||||||
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSink dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IHasPowerControl)
|
||||||
|
(dest as IHasPowerControl).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,850 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any
|
||||||
|
/// </summary>
|
||||||
|
public void RunDefaultRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if(dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = dict[routeKey];
|
||||||
|
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||||
|
// item.SourceKey, item.RouteList.Count);
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lastSource != null && lastSource is IUsageTracking)
|
||||||
|
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
|
||||||
|
//var tempAudio = new SourceRouteListItem
|
||||||
|
//{
|
||||||
|
// DestinationKey = "$defaultAudio",
|
||||||
|
// SourceKey = route.SourceKey,
|
||||||
|
// Type = eRoutingSignalType.Audio
|
||||||
|
//};
|
||||||
|
//DoRoute(tempAudio);
|
||||||
|
//continue; -- not sure why this was here
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
if (item.SourceDevice is IUsageTracking)
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control on room, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
// And finally, set the "control". This will trigger event
|
||||||
|
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "SetDefaultLevels not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
=======
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any
|
||||||
|
/// </summary>
|
||||||
|
public void RunDefaultRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if(dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = dict[routeKey];
|
||||||
|
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||||
|
// item.SourceKey, item.RouteList.Count);
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lastSource != null && lastSource is IUsageTracking)
|
||||||
|
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
|
||||||
|
//var tempAudio = new SourceRouteListItem
|
||||||
|
//{
|
||||||
|
// DestinationKey = "$defaultAudio",
|
||||||
|
// SourceKey = route.SourceKey,
|
||||||
|
// Type = eRoutingSignalType.Audio
|
||||||
|
//};
|
||||||
|
//DoRoute(tempAudio);
|
||||||
|
//continue; -- not sure why this was here
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
if (item.SourceDevice is IUsageTracking)
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control on room, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
// And finally, set the "control". This will trigger event
|
||||||
|
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "SetDefaultLevels not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
>>>>>>> origin/feature/ecs-342
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
872
PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
Normal file
872
PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
Normal file
@@ -0,0 +1,872 @@
|
|||||||
|
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;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
|
||||||
|
{
|
||||||
|
private bool _codecExternalSourceChange;
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||||
|
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Make this more specific
|
||||||
|
///// </summary>
|
||||||
|
//public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null;
|
||||||
|
//&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public AudioCodecBase AudioCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
|
||||||
|
/// tag to device.
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
|
||||||
|
var vc = VideoCodec as IHasExternalSourceSwitching;
|
||||||
|
if (vc != null && !_codecExternalSourceChange)
|
||||||
|
{
|
||||||
|
vc.SetSelectedSource(CurrentSourceInfoKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
_codecExternalSourceChange = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
CCriticalSection SourceSelectLock = new CCriticalSection();
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1Room(DeviceConfig config)
|
||||||
|
: base(config)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
|
||||||
|
(config.Properties.ToString());
|
||||||
|
DefaultDisplay = DeviceManager.GetDeviceForKey((PropertiesConfig as EssentialsHuddleVtc1PropertiesConfig).DefaultDisplayKey) as IRoutingSinkWithSwitching;
|
||||||
|
|
||||||
|
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||||
|
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||||
|
|
||||||
|
|
||||||
|
if (VideoCodec == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "No Video Codec set. Please check 'videoCodecKey' property in room config");
|
||||||
|
throw new ArgumentNullException("VideoCodec cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||||
|
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||||
|
if (AudioCodec == null)
|
||||||
|
Debug.Console(0, this, "No Audio Codec Found");
|
||||||
|
|
||||||
|
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
|
||||||
|
if (DefaultAudioDevice == null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, Debug.ErrorLogLevel.Error, "No Default Audio Device set. Please check 'defaultAudioKey' property in room config");
|
||||||
|
throw new ArgumentNullException("DefaultAudioDevice cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeRoom();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Error building room: \n{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeRoom()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (DefaultAudioDevice is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
|
||||||
|
else if (DefaultAudioDevice is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
|
||||||
|
// Combines call feedback from both codecs if available
|
||||||
|
InCallFeedback = new BoolFeedback(() =>
|
||||||
|
{
|
||||||
|
bool inAudioCall = false;
|
||||||
|
bool inVideoCall = false;
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
inAudioCall = AudioCodec.IsInCall;
|
||||||
|
|
||||||
|
if (VideoCodec != null)
|
||||||
|
inVideoCall = VideoCodec.IsInCall;
|
||||||
|
|
||||||
|
if (inAudioCall || inVideoCall)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||||
|
if (dispTwoWay != null)
|
||||||
|
{
|
||||||
|
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
|
||||||
|
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
|
||||||
|
|
||||||
|
// Get emergency object, if any
|
||||||
|
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Emergency Config evaluated.");
|
||||||
|
|
||||||
|
|
||||||
|
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SetupEnvironmentalControlDevices();
|
||||||
|
|
||||||
|
SetSourceListKey();
|
||||||
|
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "Error Initializing Room: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupEnvironmentalControlDevices()
|
||||||
|
{
|
||||||
|
if (PropertiesConfig.Environment != null)
|
||||||
|
{
|
||||||
|
if (PropertiesConfig.Environment.Enabled)
|
||||||
|
{
|
||||||
|
foreach (var d in PropertiesConfig.Environment.DeviceKeys)
|
||||||
|
{
|
||||||
|
var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
|
||||||
|
EnvironmentalControlDevices.Add(envDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void SetSourceListKey()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||||
|
{
|
||||||
|
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSourceListKey(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCodecExternalSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void CustomSetConfig(DeviceConfig config)
|
||||||
|
{
|
||||||
|
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
|
||||||
|
|
||||||
|
if (newPropertiesConfig != null)
|
||||||
|
PropertiesConfig = newPropertiesConfig;
|
||||||
|
|
||||||
|
ConfigWriter.UpdateRoomConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CustomActivate()
|
||||||
|
{
|
||||||
|
// Add Occupancy object from config
|
||||||
|
if (PropertiesConfig.Occupancy != null)
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
|
||||||
|
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
|
||||||
|
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||||
|
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||||
|
|
||||||
|
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||||
|
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||||
|
|
||||||
|
return base.CustomActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
|
||||||
|
SetDefaultLevels();
|
||||||
|
|
||||||
|
RunDefaultPresentRoute();
|
||||||
|
|
||||||
|
CrestronEnvironment.Sleep(1000);
|
||||||
|
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||||
|
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
VideoCodec.StopSharing();
|
||||||
|
VideoCodec.StandbyActivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public override bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "RunDefaultCallRoute() Currently Sharing Content: {0}", VideoCodec.SharingContentIsOnFeedback.BoolValue);
|
||||||
|
|
||||||
|
if (VideoCodec.SharingContentIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Currently sharing content. Ignoring request to run default call route.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RunRouteAction(DefaultCodecRouteString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunRouteActionCodec(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
_codecExternalSourceChange = true;
|
||||||
|
RunRouteAction(routeKey, sourceListKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="souceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sourceListKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "No sourceListKey present. RunRouteAction assumes default source list.");
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||||
|
|
||||||
|
RunRouteAction(routeKey, new Action(() => { }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
/// <param name="souceListKey"></param>
|
||||||
|
/// <param name="successCallback"></param>
|
||||||
|
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sourceListKey))
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, successCallback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||||
|
|
||||||
|
RunRouteAction(routeKey, successCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
// try to prevent multiple simultaneous selections
|
||||||
|
SourceSelectLock.TryEnter();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if this can be moved into common, base-class method -------------
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (volDev != CurrentVolumeControls)
|
||||||
|
{
|
||||||
|
// zero the volume on the device we are leaving.
|
||||||
|
// Set the volume to default on device we are entering
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
|
||||||
|
vd.SetVolume(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
|
||||||
|
{
|
||||||
|
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
|
||||||
|
vd.SetVolume(vol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
if (OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
|
||||||
|
VideoCodec.StandbyDeactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
VideoCodec.StandbyDeactivate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceSelectLock.Leave();
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSink dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSink;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||||
|
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IHasPowerControl)
|
||||||
|
(dest as IHasPowerControl).PowerOff();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool AllowVacancyTimerToStart()
|
||||||
|
{
|
||||||
|
bool allowVideo = true;
|
||||||
|
bool allowAudio = true;
|
||||||
|
|
||||||
|
if (VideoCodec != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in a video call", Key, VideoCodec.IsInCall ? "is" : "is not");
|
||||||
|
allowVideo = !VideoCodec.IsInCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AudioCodec != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in an audio call", Key, AudioCodec.IsInCall ? "is" : "is not");
|
||||||
|
allowAudio = !AudioCodec.IsInCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(2, this, "Room {0} allowing vacancy timer to start: {1}", Key, allowVideo && allowAudio);
|
||||||
|
|
||||||
|
return allowVideo && allowAudio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
if (vc != null)
|
||||||
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public override void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||||
|
/// </summary>
|
||||||
|
private void SetCodecExternalSources()
|
||||||
|
{
|
||||||
|
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||||
|
|
||||||
|
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get the tie line that the external switcher is connected to
|
||||||
|
string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
|
||||||
|
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
|
||||||
|
|
||||||
|
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||||
|
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
|
||||||
|
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||||
|
|
||||||
|
foreach (var kvp in srcList)
|
||||||
|
{
|
||||||
|
var srcConfig = kvp.Value;
|
||||||
|
|
||||||
|
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||||
|
{
|
||||||
|
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||||
|
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCodecBranding()
|
||||||
|
{
|
||||||
|
var vcWithBranding = VideoCodec as IHasBranding;
|
||||||
|
|
||||||
|
if (vcWithBranding == null) return;
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Setting Codec Branding");
|
||||||
|
vcWithBranding.InitializeBranding(Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPrivacy Members
|
||||||
|
|
||||||
|
|
||||||
|
public void PrivacyModeOff()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeOn()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeToggle()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
967
PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs.orig
Normal file
967
PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs.orig
Normal file
@@ -0,0 +1,967 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, IPrivacy
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make this more specific
|
||||||
|
/// </summary>
|
||||||
|
public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1PropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleVtc1Room(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IBasicVolumeControls defaultAudio, VideoCodecBase codec, EssentialsHuddleVtc1PropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
if (codec == null)
|
||||||
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
VideoCodec = codec;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
InCallFeedback = new BoolFeedback(() => VideoCodec.IsInCall);
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingSourceFeedback.StringValue != null);
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
RunRouteAction(DefaultCodecRouteString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
=======
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, IPrivacy
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make this more specific
|
||||||
|
/// </summary>
|
||||||
|
public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1PropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleVtc1Room(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IBasicVolumeControls defaultAudio, VideoCodecBase codec, EssentialsHuddleVtc1PropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
if (codec == null)
|
||||||
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
VideoCodec = codec;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
InCallFeedback = new BoolFeedback(() => VideoCodec.IsInCall);
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingSourceFeedback.StringValue != null);
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
RunRouteAction(DefaultCodecRouteString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
>>>>>>> origin/feature/ecs-342
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
if (vc != null)
|
||||||
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPrivacy Members
|
||||||
|
|
||||||
|
|
||||||
|
public void PrivacyModeOff()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeOn()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeToggle()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
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;
|
||||||
|
using PepperDash.Essentials.Core.Devices;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for rooms with more than a single display
|
||||||
|
/// </summary>
|
||||||
|
public abstract class EssentialsNDisplayRoomBase : EssentialsRoomBase, IHasMultipleDisplays
|
||||||
|
{
|
||||||
|
//public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
public Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching> Displays { get; protected set;}
|
||||||
|
|
||||||
|
public EssentialsNDisplayRoomBase(DeviceConfig config)
|
||||||
|
: base (config)
|
||||||
|
{
|
||||||
|
Displays = new Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching>();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
517
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
517
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
@@ -0,0 +1,517 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Crestron.SimplSharp.Scheduler;
|
||||||
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Core.Bridges;
|
||||||
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||||
|
using PepperDash.Essentials.Core.Presets;
|
||||||
|
using PepperDash.Essentials.Devices.Common;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
|
||||||
|
{
|
||||||
|
public EssentialsTechRoomConfig PropertiesConfig { get; private set; }
|
||||||
|
private readonly Dictionary<string, TwoWayDisplayBase> _displays;
|
||||||
|
|
||||||
|
private readonly DevicePresetsModel _tunerPresets;
|
||||||
|
private readonly Dictionary<string, IRSetTopBoxBase> _tuners;
|
||||||
|
|
||||||
|
private Dictionary<string, string> _currentPresets;
|
||||||
|
private ScheduledEventGroup _roomScheduledEventGroup;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsTechRoom(DeviceConfig config) : base(config)
|
||||||
|
{
|
||||||
|
PropertiesConfig = config.Properties.ToObject<EssentialsTechRoomConfig>();
|
||||||
|
|
||||||
|
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), PropertiesConfig.PresetsFileName);
|
||||||
|
|
||||||
|
_tunerPresets.SetFileName(PropertiesConfig.PresetsFileName);
|
||||||
|
|
||||||
|
_tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
|
||||||
|
|
||||||
|
_tuners = GetDevices<IRSetTopBoxBase>(PropertiesConfig.Tuners);
|
||||||
|
_displays = GetDevices<TwoWayDisplayBase>(PropertiesConfig.Displays);
|
||||||
|
|
||||||
|
RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
|
||||||
|
|
||||||
|
SetUpTunerPresetsFeedback();
|
||||||
|
|
||||||
|
SubscribeToDisplayFeedbacks();
|
||||||
|
|
||||||
|
CreateOrUpdateScheduledEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, StringFeedback> CurrentPresetsFeedbacks { get; private set; }
|
||||||
|
|
||||||
|
public Dictionary<string, IRSetTopBoxBase> Tuners
|
||||||
|
{
|
||||||
|
get { return _tuners; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, TwoWayDisplayBase> Displays
|
||||||
|
{
|
||||||
|
get { return _displays; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoolFeedback RoomPowerIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
public bool RoomPowerIsOn
|
||||||
|
{
|
||||||
|
get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ITvPresetsProvider Members
|
||||||
|
|
||||||
|
public DevicePresetsModel TvPresets
|
||||||
|
{
|
||||||
|
get { return _tunerPresets; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
||||||
|
{
|
||||||
|
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
|
||||||
|
|
||||||
|
if (!_currentPresets.ContainsKey(device.Key))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
|
||||||
|
|
||||||
|
_currentPresets[device.Key] = channel;
|
||||||
|
|
||||||
|
if (CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||||
|
{
|
||||||
|
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetUpTunerPresetsFeedback()
|
||||||
|
{
|
||||||
|
_currentPresets = new Dictionary<string, string>();
|
||||||
|
CurrentPresetsFeedbacks = new Dictionary<string, StringFeedback>();
|
||||||
|
|
||||||
|
foreach (var setTopBox in _tuners)
|
||||||
|
{
|
||||||
|
var tuner = setTopBox.Value;
|
||||||
|
_currentPresets.Add(tuner.Key, String.Empty);
|
||||||
|
CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubscribeToDisplayFeedbacks()
|
||||||
|
{
|
||||||
|
foreach (var display in _displays)
|
||||||
|
{
|
||||||
|
display.Value.PowerIsOnFeedback.OutputChange +=
|
||||||
|
(sender, args) =>
|
||||||
|
{
|
||||||
|
RoomPowerIsOnFeedback.InvokeFireUpdate();
|
||||||
|
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||||
|
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateOrUpdateScheduledEvents()
|
||||||
|
{
|
||||||
|
var eventsConfig = PropertiesConfig.ScheduledEvents;
|
||||||
|
|
||||||
|
GetOrCreateScheduleGroup();
|
||||||
|
|
||||||
|
foreach (var eventConfig in eventsConfig)
|
||||||
|
{
|
||||||
|
CreateOrUpdateSingleEvent(eventConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
_roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetOrCreateScheduleGroup()
|
||||||
|
{
|
||||||
|
if (_roomScheduledEventGroup == null)
|
||||||
|
{
|
||||||
|
_roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key);
|
||||||
|
|
||||||
|
Scheduler.AddEventGroup(_roomScheduledEventGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
_roomScheduledEventGroup.RetrieveAllEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent)
|
||||||
|
{
|
||||||
|
if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key))
|
||||||
|
{
|
||||||
|
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
|
||||||
|
|
||||||
|
//if (SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
|
||||||
|
// SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
|
||||||
|
//{
|
||||||
|
// Debug.Console(1, this, "Existing event matches new event properties. Nothing to update");
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
Debug.Console(1, this,
|
||||||
|
"Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",
|
||||||
|
roomEvent.Name);
|
||||||
|
|
||||||
|
_roomScheduledEventGroup.DeleteEvent(roomEvent);
|
||||||
|
|
||||||
|
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent)
|
||||||
|
{
|
||||||
|
//update config based on key of scheduleEvent
|
||||||
|
GetOrCreateScheduleGroup();
|
||||||
|
var existingEventIndex = PropertiesConfig.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
|
||||||
|
|
||||||
|
if (existingEventIndex < 0)
|
||||||
|
{
|
||||||
|
PropertiesConfig.ScheduledEvents.Add(scheduledEvent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PropertiesConfig.ScheduledEvents[existingEventIndex] = scheduledEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create or update event based on config
|
||||||
|
CreateOrUpdateSingleEvent(scheduledEvent);
|
||||||
|
//save config
|
||||||
|
Config.Properties = JToken.FromObject(PropertiesConfig);
|
||||||
|
|
||||||
|
CustomSetConfig(Config);
|
||||||
|
//Fire Event
|
||||||
|
OnScheduledEventUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ScheduledEventConfig> GetScheduledEvents()
|
||||||
|
{
|
||||||
|
return PropertiesConfig.ScheduledEvents ?? new List<ScheduledEventConfig>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScheduledEventUpdate()
|
||||||
|
{
|
||||||
|
var handler = ScheduledEventsChanged;
|
||||||
|
|
||||||
|
if (handler == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler(this, new ScheduledEventEventArgs {ScheduledEvents = PropertiesConfig.ScheduledEvents});
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<ScheduledEventEventArgs> ScheduledEventsChanged;
|
||||||
|
|
||||||
|
private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
|
||||||
|
{
|
||||||
|
var eventConfig = PropertiesConfig.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
|
||||||
|
|
||||||
|
if (eventConfig == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Event with name {0} not found", schevent.Name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Running actions for event {0}", schevent.Name);
|
||||||
|
|
||||||
|
if (eventConfig.Acknowledgeable)
|
||||||
|
{
|
||||||
|
schevent.Acknowledge();
|
||||||
|
}
|
||||||
|
|
||||||
|
CrestronInvoke.BeginInvoke((o) =>
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count);
|
||||||
|
|
||||||
|
foreach (var a in eventConfig.Actions)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this,
|
||||||
|
@"Attempting to run action:
|
||||||
|
Key: {0}
|
||||||
|
MethodName: {1}
|
||||||
|
Params: {2}"
|
||||||
|
, a.DeviceKey, a.MethodName, a.Params);
|
||||||
|
DeviceJsonApi.DoDeviceAction(a);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RoomPowerOn()
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Room Powering On");
|
||||||
|
|
||||||
|
var dummySource = DeviceManager.GetDeviceForKey(PropertiesConfig.DummySourceKey) as IRoutingOutputs;
|
||||||
|
|
||||||
|
if (dummySource == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Unable to get source with key: {0}", PropertiesConfig.DummySourceKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var display in _displays)
|
||||||
|
{
|
||||||
|
RunDirectRoute(dummySource, display.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RoomPowerOff()
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Room Powering Off");
|
||||||
|
|
||||||
|
foreach (var display in _displays)
|
||||||
|
{
|
||||||
|
display.Value.PowerOff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, T> GetDevices<T>(ICollection<string> config) where T : IKeyed
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var returnValue = DeviceManager.AllDevices.OfType<T>()
|
||||||
|
.Where(d => config.Contains(d.Key))
|
||||||
|
.ToDictionary(d => d.Key, d => d);
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||||
|
"Error getting devices. Check Essentials Configuration");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Overrides of EssentialsRoomBase
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get { return () => RoomPowerIsOn; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Implementation of IBridgeAdvanced
|
||||||
|
|
||||||
|
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||||
|
{
|
||||||
|
|
||||||
|
var joinMap = new EssentialsTechRoomJoinMap(joinStart);
|
||||||
|
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(joinMapSerialized))
|
||||||
|
{
|
||||||
|
joinMap = JsonConvert.DeserializeObject<EssentialsTechRoomJoinMap>(joinMapSerialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bridge != null)
|
||||||
|
{
|
||||||
|
bridge.AddJoinMap(Key, joinMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PropertiesConfig.IsPrimary)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring");
|
||||||
|
if (PropertiesConfig.MirroredTuners != null && PropertiesConfig.MirroredTuners.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var tuner in PropertiesConfig.MirroredTuners)
|
||||||
|
{
|
||||||
|
var f = CurrentPresetsFeedbacks[tuner.Value];
|
||||||
|
|
||||||
|
if (f == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Unable to find feedback with key: {0}", tuner.Value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
|
||||||
|
f.LinkInputSig(trilist.StringInput[(uint)(join)]);
|
||||||
|
Debug.Console(1, this, "Linked Current Preset feedback for tuner: {0} to serial join: {1}", tuner.Value, join);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//i = 0;
|
||||||
|
//foreach (var feedback in CurrentPresetsFeedbacks)
|
||||||
|
//{
|
||||||
|
// feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]);
|
||||||
|
// i++;
|
||||||
|
//}
|
||||||
|
|
||||||
|
trilist.OnlineStatusChange += (device, args) =>
|
||||||
|
{
|
||||||
|
if (!args.DeviceOnLine)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var feedback in CurrentPresetsFeedbacks)
|
||||||
|
{
|
||||||
|
feedback.Value.FireUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Linking Secondary system Tuner Preset Mirroring");
|
||||||
|
|
||||||
|
if (PropertiesConfig.MirroredTuners != null && PropertiesConfig.MirroredTuners.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var tuner in PropertiesConfig.MirroredTuners)
|
||||||
|
{
|
||||||
|
var t = _tuners[tuner.Value];
|
||||||
|
|
||||||
|
if (t == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
|
||||||
|
trilist.SetStringSigAction(join, s => _tunerPresets.Dial(s, t));
|
||||||
|
Debug.Console(1, this, "Linked preset recall action for tuner: {0} to serial join: {1}", tuner.Value, join);
|
||||||
|
}
|
||||||
|
|
||||||
|
//foreach (var setTopBox in _tuners)
|
||||||
|
//{
|
||||||
|
// var tuner = setTopBox;
|
||||||
|
|
||||||
|
// trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value));
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced
|
||||||
|
{
|
||||||
|
[JoinName("currentPreset")]
|
||||||
|
public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16},
|
||||||
|
new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial});
|
||||||
|
|
||||||
|
public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IRunDirectRouteAction Members
|
||||||
|
|
||||||
|
private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest)
|
||||||
|
{
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IHasPowerControl)
|
||||||
|
(dest as IHasPowerControl).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to route directly between a source and destination
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceKey"></param>
|
||||||
|
/// <param name="destinationKey"></param>
|
||||||
|
public void RunDirectRoute(string sourceKey, string destinationKey)
|
||||||
|
{
|
||||||
|
IRoutingSink dest = null;
|
||||||
|
|
||||||
|
dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink;
|
||||||
|
|
||||||
|
var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
|
||||||
|
|
||||||
|
if (source == null || dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RunDirectRoute(source, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ScheduledEventEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public List<ScheduledEventConfig> ScheduledEvents;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay, IHasCurrentVolumeControls
|
||||||
|
{
|
||||||
|
bool ExcludeFromGlobalFunctions { get; }
|
||||||
|
|
||||||
|
void RunRouteAction(string routeKey);
|
||||||
|
|
||||||
|
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
|
||||||
|
|
||||||
|
IBasicVolumeControls CurrentVolumeControls { get; }
|
||||||
|
|
||||||
|
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
using PepperDash.Essentials.Core;
|
|
||||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
using PepperDash.Essentials.Room.Config;
|
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Room
|
namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback,
|
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
|
||||||
IRoomOccupancy, IEmergency, IMicrophonePrivacy
|
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||||
{
|
{
|
||||||
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user