Compare commits

..

2 Commits

Author SHA1 Message Date
Neil Dorin
5ef7882955 Updates drawing to have correct decision labels 2020-07-28 22:58:00 -06:00
Neil Dorin
3992aba843 Adds updated plugin load sequence drawing 2020-07-27 23:38:31 -06:00
793 changed files with 120198 additions and 34034 deletions

View File

@@ -7,9 +7,6 @@ assignees: ''
---
**Was this bug identified in a specific build version?**
Please note the build version where this bug was identified
**Describe the bug**
A clear and concise description of what the bug is.

View File

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

View File

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

View File

@@ -1,8 +1,5 @@
$latestVersions = $(git tag --merged origin/main)
$latestVersions = $(git tag --merged origin/master)
$latestVersion = [version]"0.0.0"
Write-Host "GITHUB_REF: $($Env:GITHUB_REF)"
Write-Host "GITHUB_HEAD_REF: $($Env:GITHUB_HEAD_REF)"
Write-Host "GITHUB_BASE_REF: $($Env:GITHUB_BASE_REF)"
Foreach ($version in $latestVersions) {
Write-Host $version
try {
@@ -20,14 +17,8 @@ Foreach ($version in $latestVersions) {
$newVersion = [version]$latestVersion
$phase = ""
$newVersionString = ""
switch -regex ($Env:GITHUB_REF) {
'^refs\/pull\/*.' {
$splitRef = $Env:GITHUB_REF -split "/"
$phase = "pr$($splitRef[2])"
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/main*.' {
'^refs\/heads\/master*.' {
$newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build
}
'^refs\/heads\/feature\/*.' {
@@ -52,7 +43,6 @@ switch -regex ($Env:GITHUB_REF) {
$phase = 'hotfix'
$newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER
}
}

View File

@@ -8,10 +8,9 @@ $destination = "$($Env:GITHUB_HOME)\output"
New-Item -ItemType Directory -Force -Path ($destination)
Get-ChildItem ($destination)
$exclusions = @(git submodule foreach --quiet 'echo $name')
$exclusions += "Newtonsoft.Compact.Json.dll"
# Trying to get any .json schema files (not currently working)
# Gets any files with the listed extensions.
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.dll", "*.nuspec" | ForEach-Object {
Get-ChildItem -recurse -Path "$($Env:GITHUB_WORKSPACE)" -include "*.clz", "*.cpz", "*.cplz", "*.dll" | ForEach-Object {
$allowed = $true;
# Exclude any files in submodules
foreach ($exclude in $exclusions) {

View File

@@ -3,94 +3,268 @@ name: Branch Build Using Docker
on:
push:
branches:
- feature-2.0.0/*
- hotfix-2.0.0/*
- release-2.0.0/*
- development-2.0.0
- feature/*
- hotfix/*
- bugfix/*
- release/*
- development
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: .
SOLUTION_FILE: PepperDash.Essentials
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
# Defaults to master as the release branch. Change as necessary
RELEASE_BRANCH: master
jobs:
Build_Project_4-Series:
Build_Project:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
steps:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
# And any submodules
- name: Checkout submodules
shell: bash
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
# Fetch all tags
- name: Fetch tags
run: git fetch --tags
# Generate the appropriate version number
- name: Set Version Number
id: setVersion
shell: powershell
run: |
$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\/hotfix-2.0.0\/*.' {
$phase = 'hotfix'
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/release-2.0.0\/*.' {
$splitRef = $Env:GITHUB_REF -split "/"
$version = [version]($splitRef[-1] -replace "v", "")
$phase = 'rc'
$newVersionString = "{0}-{1}-{2}" -f $version, $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
}
}
echo "version=$newVersionString" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Setup MS Build
uses: microsoft/setup-msbuild@v1.1
- name: restore Nuget Packages
run: nuget restore .\$($Env:SOLUTION_FILE).sln
# Build the solutions in the docker image
- name: Build Solution
run: msbuild .\$($Env:SOLUTION_FILE).sln /p:Platform="Any CPU" /p:Configuration="Debug" /p:Version="${{ steps.setVersion.outputs.version }}" -m
- name: Pack Solution
run: dotnet pack .\$($Env:SOLUTION_FILE).sln --configuration $env:BUILD_TYPE --output ./output /p:Version="${{ steps.setVersion.outputs.version }}"
- name: Create tag for non-rc builds
if: contains(steps.setVersion.outputs.version, 'alpha')
$version = ./.github/scripts/GenerateVersionNumber.ps1
Write-Output "::set-env name=VERSION::$version"
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
git tag ${{ steps.setVersion.outputs.version }}
git push --tags origin
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
# 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
# Create the release on the source repo
- name: Create tag for non-rc builds
if: contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta')
run: |
git tag $($Env:VERSION)
git push --tags origin
- name: Create Release
id: create_release
# if: contains(steps.setVersion.outputs.version,'-rc-') ||
# contains(steps.setVersion.outputs.version,'-hotfix-') ||
# contains(steps.setVersion.outputs.version, '-beta-')
uses: ncipollo/release-action@v1
# using contributor's version to allow for pointing at the right commit
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
uses: fleskesvor/create-release@feature/support-target-commitish
with:
artifacts: 'output\**\*.*(cpz|cplz)'
generateReleaseNotes: true
tag_name: ${{ env.VERSION }}
release_name: ${{ env.VERSION }}
prerelease: ${{contains('debug', env.BUILD_TYPE)}}
tag: ${{ steps.setVersion.outputs.version }}
- name: Setup Nuget
run: |
nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username pepperdash -password ${{ secrets.GITHUB_TOKEN }}
nuget setApiKey ${{ secrets.GITHUB_TOKEN }} -Source github
nuget setApiKey ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json
- name: Publish to Nuget
run: nuget push .\output\*.nupkg -Source https://api.nuget.org/v3/index.json
- name: Publish to Github Nuget
run: nuget push .\output\*.nupkg -Source github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload the build package to the release
- name: Upload Release Package
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
id: upload_release
uses: actions/upload-release-asset@v1
with:
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 }}
# This step always runs and pushes the build to the internal build rep
Internal_Push_Output:
needs: Build_Project
runs-on: windows-latest
steps:
- name: check Github ref
run: ${{toJson(github.ref)}}
# Checkout the repo
- name: Checkout Builds Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.BUILDS_TOKEN }}
repository: PepperDash-Engineering/essentials-builds
ref: ${{ Env.GITHUB_REF }}
# Download the version artifact from the build job
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Check Directory
run: Get-ChildItem "./"
# Set the version number environment variable from the file we just downloaded
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Create new branch
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- 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
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: |
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
Write-Host "Branch: $branch"
git push -u origin $($branch) --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./
# This step only runs if the branch is master or release/ runs and pushes the build to the public build repo
Public_Push_Output:
needs: Build_Project
runs-on: windows-latest
if: contains(github.ref, 'master') || contains(github.ref, '/release/')
steps:
# Checkout the repo
- name: check Github ref
run: ${{toJson(github.ref)}}
- name: Checkout Builds Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.BUILDS_TOKEN }}
repository: PepperDash/Essentials-Builds
ref: ${{ Env.GITHUB_REF }}
# Download the version artifact from the build job
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Check Directory
run: Get-ChildItem "./"
# Set the version number environment variable from the file we just downloaded
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Create new branch
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- 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
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: |
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
Write-Host "Branch: $branch"
git push -u origin $($branch) --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./

View File

@@ -1,57 +0,0 @@
name: main Build using Docker
on:
release:
types:
- published
branches:
- main-2.0.0
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@v3
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
id: setVersion
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Setup MS Build
uses: microsoft/setup-msbuild@v1.1
- name: restore Nuget Packages
run: nuget restore .\$($Env:SOLUTION_FILE).sln
- name: Build Solution
run: msbuild .\$($Env:SOLUTION_FILE).sln /p:Platform="Any CPU" /p:Configuration="Debug" /p:Version="${{ steps.setVersion.outputs.version }}" -m
- name: Pack Solution
run: dotnet pack .\$($Env:SOLUTION_FILE).sln --configuration $env:BUILD_TYPE --output ./output /p:Version="${{ steps.setVersion.outputs.version }}"
- name: Upload Release
id: create_release
uses: ncipollo/release-action@v1
with:
updateRelease: true
artifacts: 'output\**\*.*(cpz|cplz)'
tag: ${{ steps.setVersion.outputs.version }}
- name: Setup Nuget
run: |
nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username pepperdash -password ${{ secrets.GITHUB_TOKEN }}
nuget setApiKey ${{ secrets.GITHUB_TOKEN }} -Source github
nuget setApiKey ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json
- name: Publish to Nuget
run: nuget push .\output\*.nupkg -Source https://api.nuget.org/v3/index.json
- name: Publish to Github Nuget
run: nuget push .\output\*.nupkg -Source github

232
.github/workflows/master.yml vendored Normal file
View File

@@ -0,0 +1,232 @@
name: Master Build using Docker
on:
release:
types:
- created
branches:
- master
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 master as the release branch. Change as necessary
RELEASE_BRANCH: master
jobs:
Build_Project:
runs-on: windows-latest
steps:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
# And any submodules
- name: Checkout submodules
shell: bash
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: Write-Output "::set-env name=VERSION::$($Env:TAG_NAME)"
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
# 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 }}
Internal_Push_Output:
needs: Build_Project
runs-on: windows-latest
steps:
# Checkout the repo
- name: Checkout Builds Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.BUILDS_TOKEN }}
repository: PepperDash-Engineering/essentials-builds
ref: ${{ Env.GITHUB_REF }}
# Download the version artifact from the build job
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Check Directory
run: Get-ChildItem "./"
# Set the version number environment variable from the file we just downloaded
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Checkout Master branch
run: git checkout master
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- 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
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: git push -u origin master --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./
# This step only runs if the branch is master or release/ runs and pushes the build to the public build repo
Public_Push_Output:
needs: Build_Project
runs-on: windows-latest
steps:
# Checkout the repo
- name: Checkout Builds Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.BUILDS_TOKEN }}
repository: PepperDash/Essentials-Builds
ref: ${{ Env.GITHUB_REF }}
# Download the version artifact from the build job
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Check Directory
run: Get-ChildItem "./"
# Set the version number environment variable from the file we just downloaded
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout master branch
- name: Create new branch
run: git checkout master
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- 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
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: git push -u origin master --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./

367
.gitignore vendored
View File

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

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "essentials-framework/pepperdashcore-builds"]
path = essentials-framework/pepperdashcore-builds
url = https://github.com/ndorin/PepperDashCore-Builds.git
[submodule "Essentials-Template-UI"]
path = Essentials-Template-UI
url = https://github.com/PepperDash/Essentials-Template-UI.git

Binary file not shown.

Binary file not shown.

View File

@@ -1,44 +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}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials", "src\PepperDash.Essentials\PepperDash.Essentials.csproj", "{CB3B11BA-625C-4D35-B663-FDC5BE9A230E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PepperDash.Essentials.Core", "src\PepperDash.Essentials.Core\PepperDash.Essentials.Core.csproj", "{3D192FED-8FFC-4CB5-B5F7-BA307ABA254B}"
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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6907A4BF-7201-47CF-AAB1-3597F3B8E1C3}
EndGlobalSection
EndGlobal

49
PepperDashEssentials.sln Normal file
View 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

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class IChannelExtensions
{
public static void LinkActions(this IChannel dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "chanUp", new PressAndHoldAction(dev.ChannelUp));
controller.AddAction(prefix + "chanDown", new PressAndHoldAction(dev.ChannelDown));
controller.AddAction(prefix + "lastChan", new PressAndHoldAction(dev.LastChannel));
controller.AddAction(prefix + "guide", new PressAndHoldAction(dev.Guide));
controller.AddAction(prefix + "info", new PressAndHoldAction(dev.Info));
controller.AddAction(prefix + "exit", new PressAndHoldAction(dev.Exit));
}
public static void UnlinkActions(this IChannel dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "chanUp");
controller.RemoveAction(prefix + "chanDown");
controller.RemoveAction(prefix + "lastChan");
controller.RemoveAction(prefix + "guide");
controller.RemoveAction(prefix + "info");
controller.RemoveAction(prefix + "exit");
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class IColorExtensions
{
public static void LinkActions(this IColor dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "red", new PressAndHoldAction(dev.Red));
controller.AddAction(prefix + "green", new PressAndHoldAction(dev.Green));
controller.AddAction(prefix + "yellow", new PressAndHoldAction(dev.Yellow));
controller.AddAction(prefix + "blue", new PressAndHoldAction(dev.Blue));
}
public static void UnlinkActions(this IColor dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "red");
controller.RemoveAction(prefix + "green");
controller.RemoveAction(prefix + "yellow");
controller.RemoveAction(prefix + "blue");
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class IDPadExtensions
{
public static void LinkActions(this IDPad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "up", new PressAndHoldAction(dev.Up));
controller.AddAction(prefix + "down", new PressAndHoldAction(dev.Down));
controller.AddAction(prefix + "left", new PressAndHoldAction(dev.Left));
controller.AddAction(prefix + "right", new PressAndHoldAction(dev.Right));
controller.AddAction(prefix + "select", new PressAndHoldAction(dev.Select));
controller.AddAction(prefix + "menu", new PressAndHoldAction(dev.Menu));
controller.AddAction(prefix + "exit", new PressAndHoldAction(dev.Exit));
}
public static void UnlinkActions(this IDPad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "up");
controller.RemoveAction(prefix + "down");
controller.RemoveAction(prefix + "left");
controller.RemoveAction(prefix + "right");
controller.RemoveAction(prefix + "select");
controller.RemoveAction(prefix + "menu");
controller.RemoveAction(prefix + "exit");
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class IDvrExtensions
{
public static void LinkActions(this IDvr dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "dvrlist", new PressAndHoldAction(dev.DvrList));
controller.AddAction(prefix + "record", new PressAndHoldAction(dev.Record));
}
public static void UnlinkActions(this IDvr dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "dvrlist");
controller.RemoveAction(prefix + "record");
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class INumericExtensions
{
public static void LinkActions(this INumericKeypad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "num0", new PressAndHoldAction(dev.Digit0));
controller.AddAction(prefix + "num1", new PressAndHoldAction(dev.Digit1));
controller.AddAction(prefix + "num2", new PressAndHoldAction(dev.Digit2));
controller.AddAction(prefix + "num3", new PressAndHoldAction(dev.Digit3));
controller.AddAction(prefix + "num4", new PressAndHoldAction(dev.Digit4));
controller.AddAction(prefix + "num5", new PressAndHoldAction(dev.Digit5));
controller.AddAction(prefix + "num6", new PressAndHoldAction(dev.Digit6));
controller.AddAction(prefix + "num7", new PressAndHoldAction(dev.Digit0));
controller.AddAction(prefix + "num8", new PressAndHoldAction(dev.Digit0));
controller.AddAction(prefix + "num9", new PressAndHoldAction(dev.Digit0));
controller.AddAction(prefix + "numDash", new PressAndHoldAction(dev.KeypadAccessoryButton1));
controller.AddAction(prefix + "numEnter", new PressAndHoldAction(dev.KeypadAccessoryButton2));
// Deal with the Accessory functions on the numpad later
}
public static void UnlinkActions(this INumericKeypad dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "num0");
controller.RemoveAction(prefix + "num1");
controller.RemoveAction(prefix + "num2");
controller.RemoveAction(prefix + "num3");
controller.RemoveAction(prefix + "num4");
controller.RemoveAction(prefix + "num5");
controller.RemoveAction(prefix + "num6");
controller.RemoveAction(prefix + "num7");
controller.RemoveAction(prefix + "num8");
controller.RemoveAction(prefix + "num9");
controller.RemoveAction(prefix + "numDash");
controller.RemoveAction(prefix + "numEnter");
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class IPowerExtensions
{
public static void LinkActions(this IPower dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "powerOn", new Action(dev.PowerOn));
controller.AddAction(prefix + "powerOff", new Action(dev.PowerOff));
controller.AddAction(prefix + "powerToggle", new Action(dev.PowerToggle));
}
public static void UnlinkActions(this IPower dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "powerOn");
controller.RemoveAction(prefix + "powerOff");
controller.RemoveAction(prefix + "powerToggle");
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class ISetTopBoxControlsExtensions
{
public static void LinkActions(this ISetTopBoxControls dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "dvrList", new PressAndHoldAction(dev.DvrList));
controller.AddAction(prefix + "replay", new PressAndHoldAction(dev.Replay));
}
public static void UnlinkActions(this ISetTopBoxControls dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "dvrList");
controller.RemoveAction(prefix + "replay");
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
using PepperDash.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
public static class ITransportExtensions
{
public static void LinkActions(this ITransport dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.AddAction(prefix + "play", new PressAndHoldAction(dev.Play));
controller.AddAction(prefix + "pause", new PressAndHoldAction(dev.Pause));
controller.AddAction(prefix + "stop", new PressAndHoldAction(dev.Stop));
controller.AddAction(prefix + "prevTrack", new PressAndHoldAction(dev.ChapPlus));
controller.AddAction(prefix + "nextTrack", new PressAndHoldAction(dev.ChapMinus));
controller.AddAction(prefix + "rewind", new PressAndHoldAction(dev.Rewind));
controller.AddAction(prefix + "ffwd", new PressAndHoldAction(dev.FFwd));
controller.AddAction(prefix + "record", new PressAndHoldAction(dev.Record));
}
public static void UnlinkActions(this ITransport dev, MobileControlSystemController controller)
{
var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
controller.RemoveAction(prefix + "play");
controller.RemoveAction(prefix + "pause");
controller.RemoveAction(prefix + "stop");
controller.RemoveAction(prefix + "prevTrack");
controller.RemoveAction(prefix + "nextTrack");
controller.RemoveAction(prefix + "rewind");
controller.RemoveAction(prefix + "ffwd");
controller.RemoveAction(prefix + "record");
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
/// <summary>
/// Represents a room whose configuration is derived from runtime data,
/// perhaps from another program, and that the data may not be fully
/// available at startup.
/// </summary>
public interface IDelayedConfiguration
{
event EventHandler<EventArgs> ConfigurationIsReady;
}
}

View File

@@ -0,0 +1,102 @@
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.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge for an AudioCodecBase device
/// </summary>
public class AudioCodecBaseMessenger : MessengerBase
{
/// <summary>
/// Device being bridged
/// </summary>
public AudioCodecBase Codec { get; set; }
/// <summary>
/// Constuctor
/// </summary>
/// <param name="key"></param>
/// <param name="codec"></param>
/// <param name="messagePath"></param>
public AudioCodecBaseMessenger(string key, AudioCodecBase codec, string messagePath)
: base(key, messagePath)
{
if (codec == null)
throw new ArgumentNullException("codec");
Codec = codec;
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendAtcFullMessageObject));
appServerController.AddAction(MessagePath + "/dial", new Action<string>(s => Codec.Dial(s)));
appServerController.AddAction(MessagePath + "/endCallById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.EndCall(call);
}));
appServerController.AddAction(MessagePath + "/endAllCalls", new Action(Codec.EndAllCalls));
appServerController.AddAction(MessagePath + "/dtmf", new Action<string>(s => Codec.SendDtmf(s)));
appServerController.AddAction(MessagePath + "/rejectById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.RejectCall(call);
}));
appServerController.AddAction(MessagePath + "/acceptById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.AcceptCall(call);
}));
}
/// <summary>
/// Helper to grab a call with string ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
CodecActiveCallItem GetCallWithId(string id)
{
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
}
void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
SendAtcFullMessageObject();
}
/// <summary>
/// Helper method to build call status for vtc
/// </summary>
/// <returns></returns>
void SendAtcFullMessageObject()
{
var info = Codec.CodecInfo;
PostStatusMessage(new
{
isInCall = Codec.IsInCall,
calls = Codec.ActiveCalls,
info = new
{
phoneNumber = info.PhoneNumber
}
});
}
}
}

View File

@@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class CameraBaseMessenger : MessengerBase
{
/// <summary>
/// Device being bridged
/// </summary>
public CameraBase Camera { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="key"></param>
/// <param name="camera"></param>
/// <param name="messagePath"></param>
public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
: base(key, messagePath)
{
if (camera == null)
throw new ArgumentNullException("camera");
Camera = camera;
var presetsCamera = Camera as IHasCameraPresets;
if (presetsCamera != null)
{
presetsCamera.PresetsListHasChanged += new EventHandler<EventArgs>(presetsCamera_PresetsListHasChanged);
}
}
void presetsCamera_PresetsListHasChanged(object sender, EventArgs e)
{
var presetsCamera = Camera as IHasCameraPresets;
var presetList = new List<CameraPreset>();
if (presetsCamera != null)
presetList = presetsCamera.Presets;
PostStatusMessage(new
{
presets = presetList
});
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendCameraFullMessageObject));
var ptzCamera = Camera as IHasCameraPtzControl;
if (ptzCamera != null)
{
// Need to evaluate how to pass through these P&H actions. Need a method that takes a bool maybe?
AppServerController.AddAction(MessagePath + "/cameraUp", new PressAndHoldAction((b) =>
{
if (b)
ptzCamera.TiltUp();
else
ptzCamera.TiltStop();
}));
AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction((b) =>
{
if (b)
ptzCamera.TiltDown();
else
ptzCamera.TiltStop();
}));
AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction((b) =>
{
if (b)
ptzCamera.PanLeft();
else
ptzCamera.PanStop();
}));
AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction((b) =>
{
if (b)
ptzCamera.PanRight();
else
ptzCamera.PanStop();
}));
AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction((b) =>
{
if (b)
ptzCamera.ZoomIn();
else
ptzCamera.ZoomStop();
}));
AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction((b) =>
{
if (b)
ptzCamera.ZoomOut();
else
ptzCamera.ZoomStop();
}));
}
if (Camera is IHasCameraAutoMode)
{
appServerController.AddAction(MessagePath + "/cameraModeAuto", new Action((Camera as IHasCameraAutoMode).CameraAutoModeOn));
appServerController.AddAction(MessagePath + "/cameraModeManual", new Action((Camera as IHasCameraAutoMode).CameraAutoModeOff));
}
if (Camera is IPower)
{
appServerController.AddAction(MessagePath + "/cameraModeOff", new Action((Camera as IPower).PowerOff));
}
var presetsCamera = Camera as IHasCameraPresets;
if (presetsCamera != null)
{
for(int i = 1; i <= 6; i++)
{
var preset = i;
appServerController.AddAction(MessagePath + "/cameraPreset" + i, new Action<int>((p) => presetsCamera.PresetSelect(preset)));
}
}
}
/// <summary>
/// Helper method to update the full status of the camera
/// </summary>
void SendCameraFullMessageObject()
{
var presetsCamera = Camera as IHasCameraPresets;
var presetList = new List<CameraPreset>();
if (presetsCamera != null)
presetList = presetsCamera.Presets;
PostStatusMessage(new
{
cameraMode = GetCameraMode(),
hasPresets = Camera is IHasCameraPresets,
presets = presetList
});
}
/// <summary>
/// Computes the current camera mode
/// </summary>
/// <returns></returns>
string GetCameraMode()
{
string m;
if (Camera is IHasCameraAutoMode && (Camera as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.BoolValue)
m = eCameraControlMode.Auto.ToString().ToLower();
else if (Camera is IPower && !(Camera as IPower).PowerIsOnFeedback.BoolValue)
m = eCameraControlMode.Off.ToString().ToLower();
else
m = eCameraControlMode.Manual.ToString().ToLower();
return m;
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Handles interactions with the app server to update the config
/// </summary>
public class ConfigMessenger : MessengerBase
{
public ConfigMessenger(string key, string messagePath)
: base(key, messagePath)
{
ConfigUpdater.ConfigStatusChanged -= ConfigUpdater_ConfigStatusChanged;
ConfigUpdater.ConfigStatusChanged += new EventHandler<ConfigStatusEventArgs>(ConfigUpdater_ConfigStatusChanged);
}
void ConfigUpdater_ConfigStatusChanged(object sender, ConfigStatusEventArgs e)
{
PostUpdateStatus(e.UpdateStatus.ToString());
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/updateConfig", new Action<string>(s => GetConfigFile(s)));
}
/// <summary>
/// Generates or passes the URL to make the request to GET the config from a server
/// </summary>
/// <param name="url"></param>
void GetConfigFile(string url)
{
try
{
// Attempt to parse the URL
var parser = new Crestron.SimplSharp.Net.Http.UrlParser(url);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully parsed URL from AppServer message: {0}", parser.Url);
}
catch (Exception e)
{
// If unable to parse the URL, generate it from config data
Debug.Console(2, "Error parsing URL: {0}", e);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to parse URL from AppServer message. Generating URL from config data");
url = string.Format("http://{0}/api/system/{1}/config", AppServerController.Config.ServerUrl, AppServerController.SystemUuid);
}
ConfigUpdater.GetConfigFromServer(url);
}
/// <summary>
/// Posts a message with the current status of the config update
/// </summary>
/// <param name="status"></param>
void PostUpdateStatus(string status)
{
PostStatusMessage(new
{
updateStatus = status
});
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class IRunRouteActionMessenger : MessengerBase
{
/// <summary>
/// Device being bridged
/// </summary>
public IRunRouteAction RoutingDevice {get; private set;}
public IRunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath)
: base(key, messagePath)
{
if (routingDevice == null)
throw new ArgumentNullException("routingDevice");
RoutingDevice = routingDevice;
var routingSink = RoutingDevice as IRoutingSinkNoSwitching;
if (routingSink != null)
{
routingSink.CurrentSourceChange += new SourceInfoChangeHandler(routingSink_CurrentSourceChange);
}
}
void routingSink_CurrentSourceChange(SourceListItem info, ChangeType type)
{
SendRoutingFullMessageObject();
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendRoutingFullMessageObject));
appServerController.AddAction(MessagePath + "/source", new Action<SourceSelectMessageContent>(c =>
{
RoutingDevice.RunRouteAction(c.SourceListItem, c.SourceListKey);
}));
var sinkDevice = RoutingDevice as IRoutingSinkNoSwitching;
if(sinkDevice != null)
{
sinkDevice.CurrentSourceChange += new SourceInfoChangeHandler((o, a) =>
{
SendRoutingFullMessageObject();
});
}
}
/// <summary>
/// Helper method to update full status of the routing device
/// </summary>
void SendRoutingFullMessageObject()
{
var sinkDevice = RoutingDevice as IRoutingSinkNoSwitching;
if(sinkDevice != null)
{
var sourceKey = sinkDevice.CurrentSourceInfoKey;
if (string.IsNullOrEmpty(sourceKey))
sourceKey = "none";
PostStatusMessage(new
{
selectedSourceKey = sourceKey
});
}
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge for a VideoCodecBase
/// </summary>
public abstract class MessengerBase : IKeyed
{
public string Key { get; private set; }
/// <summary>
///
/// </summary>
public MobileControlSystemController AppServerController { get; private set; }
public string MessagePath { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="codec"></param>
public MessengerBase(string key, string messagePath)
{
Key = key;
if (string.IsNullOrEmpty(messagePath))
throw new ArgumentException("messagePath must not be empty or null");
MessagePath = messagePath;
}
/// <summary>
/// Registers this messenger with appserver controller
/// </summary>
/// <param name="appServerController"></param>
public void RegisterWithAppServer(MobileControlSystemController appServerController)
{
if (appServerController == null)
throw new ArgumentNullException("appServerController");
AppServerController = appServerController;
CustomRegisterWithAppServer(AppServerController);
}
/// <summary>
/// Implemented in extending classes. Wire up API calls and feedback here
/// </summary>
/// <param name="appServerController"></param>
abstract protected void CustomRegisterWithAppServer(MobileControlSystemController appServerController);
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="contentObject">The contents of the content object</param>
protected void PostStatusMessage(object contentObject)
{
if (AppServerController != null)
{
AppServerController.SendMessageToServer(JObject.FromObject(new
{
type = MessagePath,
content = contentObject
}));
}
}
}
}

View File

@@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SIMPLAtcMessenger : MessengerBase
{
BasicTriList EISC;
public SIMPLAtcJoinMap JoinMap {get; private set;}
///// <summary>
///// 221
///// </summary>
//const uint BDialHangupOnHook = 221;
///// <summary>
///// 251
///// </summary>
//const uint BIncomingAnswer = 251;
///// <summary>
///// 252
///// </summary>
//const uint BIncomingReject = 252;
///// <summary>
///// 241
///// </summary>
//const uint BSpeedDial1 = 241;
///// <summary>
///// 242
///// </summary>
//const uint BSpeedDial2 = 242;
///// <summary>
///// 243
///// </summary>
//const uint BSpeedDial3 = 243;
///// <summary>
///// 244
///// </summary>
//const uint BSpeedDial4 = 244;
///// <summary>
///// 201
///// </summary>
//const uint SCurrentDialString = 201;
///// <summary>
///// 211
///// </summary>
//const uint SCurrentCallNumber = 211;
///// <summary>
///// 212
///// </summary>
//const uint SCurrentCallName = 212;
///// <summary>
///// 221
///// </summary>
//const uint SHookState = 221;
///// <summary>
///// 222
///// </summary>
//const uint SCallDirection = 222;
///// <summary>
///// 201-212 0-9*#
///// </summary>
//Dictionary<string, uint> DTMFMap = new Dictionary<string, uint>
//{
// { "1", 201 },
// { "2", 202 },
// { "3", 203 },
// { "4", 204 },
// { "5", 205 },
// { "6", 206 },
// { "7", 207 },
// { "8", 208 },
// { "9", 209 },
// { "0", 210 },
// { "*", 211 },
// { "#", 212 },
//};
/// <summary>
///
/// </summary>
CodecActiveCallItem CurrentCallItem;
/// <summary>
///
/// </summary>
/// <param name="eisc"></param>
/// <param name="messagePath"></param>
public SIMPLAtcMessenger(string key, BasicTriList eisc, string messagePath)
: base(key, messagePath)
{
EISC = eisc;
JoinMap = new SIMPLAtcJoinMap(201);
CurrentCallItem = new CodecActiveCallItem();
CurrentCallItem.Type = eCodecCallType.Audio;
CurrentCallItem.Id = "-audio-";
}
/// <summary>
///
/// </summary>
void SendFullStatus()
{
this.PostStatusMessage(new
{
calls = GetCurrentCallList(),
currentCallString = EISC.GetString(JoinMap.CurrentCallName.JoinNumber),
currentDialString = EISC.GetString(JoinMap.CurrentDialString.JoinNumber),
isInCall = EISC.GetString(JoinMap.HookState.JoinNumber) == "Connected"
});
}
/// <summary>
///
/// </summary>
/// <param name="appServerController"></param>
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
//EISC.SetStringSigAction(SCurrentDialString, s => PostStatusMessage(new { currentDialString = s }));
EISC.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
{
CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
//GetCurrentCallList();
SendFullStatus();
});
EISC.SetStringSigAction(JoinMap.CurrentCallNumber.JoinNumber, s =>
{
CurrentCallItem.Number = s;
SendCallsList();
});
EISC.SetStringSigAction(JoinMap.CurrentCallName.JoinNumber, s =>
{
CurrentCallItem.Name = s;
SendCallsList();
});
EISC.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s =>
{
CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
SendCallsList();
});
// Add press and holds using helper
Action<string, uint> addPHAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b)));
// Add straight pulse calls
Action<string, uint> addAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100)));
addAction("/endCallById", JoinMap.EndCall.JoinNumber);
addAction("/endAllCalls", JoinMap.EndCall.JoinNumber);
addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber);
addAction("/rejectById", JoinMap.IncomingReject.JoinNumber);
var speeddialStart = JoinMap.SpeedDialStart.JoinNumber;
var speeddialEnd = JoinMap.SpeedDialStart.JoinNumber + JoinMap.SpeedDialStart.JoinSpan;
var speedDialIndex = 1;
for (uint i = speeddialStart; i < speeddialEnd; i++)
{
addAction(string.Format("/speedDial{0}", speedDialIndex), i);
speedDialIndex++;
}
// Get status
AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatus));
// Dial on string
AppServerController.AddAction(MessagePath + "/dial", new Action<string>(s => EISC.SetString(JoinMap.CurrentDialString.JoinNumber, s)));
// Pulse DTMF
AppServerController.AddAction(MessagePath + "/dtmf", new Action<string>(s =>
{
var join = JoinMap.Joins[s];
if (join != null)
{
if (join.JoinNumber > 0)
{
EISC.PulseBool(join.JoinNumber, 100);
}
}
}));
}
/// <summary>
///
/// </summary>
void SendCallsList()
{
PostStatusMessage(new
{
calls = GetCurrentCallList(),
});
}
/// <summary>
/// Turns the
/// </summary>
/// <returns></returns>
List<CodecActiveCallItem> GetCurrentCallList()
{
if (CurrentCallItem.Status == eCodecCallStatus.Disconnected)
{
return new List<CodecActiveCallItem>();
}
else
{
return new List<CodecActiveCallItem>() { CurrentCallItem };
}
}
}
}

View File

@@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Bridges;
using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SIMPLCameraMessenger : MessengerBase
{
BasicTriList EISC;
CameraControllerJoinMap JoinMap;
public SIMPLCameraMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart)
: base(key, messagePath)
{
EISC = eisc;
JoinMap = new CameraControllerJoinMap(joinStart);
EISC.SetUShortSigAction(JoinMap.NumberOfPresets.JoinNumber, (u) => SendCameraFullMessageObject());
EISC.SetBoolSigAction(JoinMap.CameraModeAuto.JoinNumber, (b) => PostCameraMode());
EISC.SetBoolSigAction(JoinMap.CameraModeManual.JoinNumber, (b) => PostCameraMode());
EISC.SetBoolSigAction(JoinMap.CameraModeOff.JoinNumber, (b) => PostCameraMode());
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
var asc = appServerController;
asc.AddAction(MessagePath + "/fullStatus", new Action(SendCameraFullMessageObject));
// Add press and holds using helper action
Action<string, uint> addPHAction = (s, u) =>
asc.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b)));
addPHAction("/cameraUp", JoinMap.TiltUp.JoinNumber);
addPHAction("/cameraDown", JoinMap.TiltDown.JoinNumber);
addPHAction("/cameraLeft", JoinMap.PanLeft.JoinNumber);
addPHAction("/cameraRight", JoinMap.PanRight.JoinNumber);
addPHAction("/cameraZoomIn", JoinMap.ZoomIn.JoinNumber);
addPHAction("/cameraZoomOut", JoinMap.ZoomOut.JoinNumber);
Action<string, uint> addAction = (s, u) =>
asc.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100)));
addAction("/cameraModeAuto", JoinMap.CameraModeAuto.JoinNumber);
addAction("/cameraModeManual", JoinMap.CameraModeManual.JoinNumber);
addAction("/cameraModeOff", JoinMap.CameraModeOff.JoinNumber);
var presetStart = JoinMap.PresetRecallStart.JoinNumber;
var presetEnd = JoinMap.PresetRecallStart.JoinNumber + JoinMap.PresetRecallStart.JoinSpan;
int presetId = 1;
// camera presets
for (uint i = presetStart; i <= presetEnd; i++)
{
addAction("/cameraPreset" + (presetId), i);
presetId++;
}
}
public void CustomUnregsiterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.RemoveAction(MessagePath + "/fullStatus");
appServerController.RemoveAction(MessagePath + "/cameraUp");
appServerController.RemoveAction(MessagePath + "/cameraDown");
appServerController.RemoveAction(MessagePath + "/cameraLeft");
appServerController.RemoveAction(MessagePath + "/cameraRight");
appServerController.RemoveAction(MessagePath + "/cameraZoomIn");
appServerController.RemoveAction(MessagePath + "/cameraZoomOut");
appServerController.RemoveAction(MessagePath + "/cameraModeAuto");
appServerController.RemoveAction(MessagePath + "/cameraModeManual");
appServerController.RemoveAction(MessagePath + "/cameraModeOff");
EISC.SetUShortSigAction(JoinMap.NumberOfPresets.JoinNumber, null);
EISC.SetBoolSigAction(JoinMap.CameraModeAuto.JoinNumber, null);
EISC.SetBoolSigAction(JoinMap.CameraModeManual.JoinNumber, null);
EISC.SetBoolSigAction(JoinMap.CameraModeOff.JoinNumber, null);
}
/// <summary>
/// Helper method to update the full status of the camera
/// </summary>
void SendCameraFullMessageObject()
{
var presetList = new List<CameraPreset>();
// Build a list of camera presets based on the names and count
if (EISC.GetBool(JoinMap.SupportsPresets.JoinNumber))
{
var presetStart = JoinMap.PresetLabelStart.JoinNumber;
var presetEnd = JoinMap.PresetLabelStart.JoinNumber + JoinMap.NumberOfPresets.JoinNumber;
var presetId = 1;
for (uint i = presetStart; i < presetEnd; i++)
{
var presetName = EISC.GetString(i);
var preset = new CameraPreset(presetId, presetName, string.IsNullOrEmpty(presetName), true);
presetList.Add(preset);
presetId++;
}
}
PostStatusMessage(new
{
cameraMode = GetCameraMode(),
hasPresets = EISC.GetBool(JoinMap.SupportsPresets.JoinNumber),
presets = presetList
});
}
/// <summary>
///
/// </summary>
void PostCameraMode()
{
PostStatusMessage(new
{
cameraMode = GetCameraMode()
});
}
/// <summary>
/// Computes the current camera mode
/// </summary>
/// <returns></returns>
string GetCameraMode()
{
string m;
if (EISC.GetBool(JoinMap.CameraModeAuto.JoinNumber)) m = eCameraControlMode.Auto.ToString().ToLower();
else if (EISC.GetBool(JoinMap.CameraModeManual.JoinNumber)) m = eCameraControlMode.Manual.ToString().ToLower();
else m = eCameraControlMode.Off.ToString().ToLower();
return m;
}
}
}

View File

@@ -0,0 +1,73 @@
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;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SIMPLRouteMessenger : MessengerBase
{
BasicTriList EISC;
uint JoinStart;
public class StringJoin
{
/// <summary>
/// 1
/// </summary>
public const uint CurrentSource = 1;
}
public SIMPLRouteMessenger(string key, BasicTriList eisc, string messagePath, uint joinStart)
: base(key, messagePath)
{
EISC = eisc;
JoinStart = joinStart - 1;
EISC.SetStringSigAction(JoinStart + StringJoin.CurrentSource, (s) => SendRoutingFullMessageObject(s));
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction(MessagePath + "/fullStatus", new Action(() =>
{
SendRoutingFullMessageObject(EISC.GetString(JoinStart + StringJoin.CurrentSource));
}));
appServerController.AddAction(MessagePath +"/source", new Action<SourceSelectMessageContent>(c =>
{
EISC.SetString(JoinStart + StringJoin.CurrentSource, c.SourceListItem);
}));
}
public void CustomUnregsiterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.RemoveAction(MessagePath + "/fullStatus");
appServerController.RemoveAction(MessagePath + "/source");
EISC.SetStringSigAction(JoinStart + StringJoin.CurrentSource, null);
}
/// <summary>
/// Helper method to update full status of the routing device
/// </summary>
void SendRoutingFullMessageObject(string sourceKey)
{
if (string.IsNullOrEmpty(sourceKey))
sourceKey = "none";
PostStatusMessage(new
{
selectedSourceKey = sourceKey
});
}
}
}

View File

@@ -0,0 +1,665 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.Cameras;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SIMPLVtcMessenger : MessengerBase
{
BasicTriList EISC;
public SIMPLVtcJoinMap JoinMap { get; private set; }
///********* Bools *********/
///// <summary>
///// 724
///// </summary>
//const uint BDialHangup = 724;
///// <summary>
///// 750
///// </summary>
//const uint BCallIncoming = 750;
///// <summary>
///// 751
///// </summary>
//const uint BIncomingAnswer = 751;
///// <summary>
///// 752
///// </summary>
//const uint BIncomingReject = 752;
///// <summary>
///// 741
///// </summary>
//const uint BSpeedDial1 = 741;
///// <summary>
///// 742
///// </summary>
//const uint BSpeedDial2 = 742;
///// <summary>
///// 743
///// </summary>
//const uint BSpeedDial3 = 743;
///// <summary>
///// 744
///// </summary>
//const uint BSpeedDial4 = 744;
///// <summary>
///// 800
///// </summary>
//const uint BDirectorySearchBusy = 800;
///// <summary>
///// 801
///// </summary>
//const uint BDirectoryLineSelected = 801;
///// <summary>
///// 801 when selected entry is a contact
///// </summary>
//const uint BDirectoryEntryIsContact = 801;
///// <summary>
///// 802 To show/hide back button
///// </summary>
//const uint BDirectoryIsRoot = 802;
///// <summary>
///// 803 Pulse from system to inform us when directory is ready
///// </summary>
//const uint BDirectoryHasChanged = 803;
///// <summary>
///// 804
///// </summary>
//const uint BDirectoryRoot = 804;
///// <summary>
///// 805
///// </summary>
//const uint BDirectoryFolderBack = 805;
///// <summary>
///// 806
///// </summary>
//const uint BDirectoryDialSelectedLine = 806;
///// <summary>
///// 811
///// </summary>
//const uint BCameraControlUp = 811;
///// <summary>
///// 812
///// </summary>
//const uint BCameraControlDown = 812;
///// <summary>
///// 813
///// </summary>
//const uint BCameraControlLeft = 813;
///// <summary>
///// 814
///// </summary>
//const uint BCameraControlRight = 814;
///// <summary>
///// 815
///// </summary>
//const uint BCameraControlZoomIn = 815;
///// <summary>
///// 816
///// </summary>
//const uint BCameraControlZoomOut = 816;
///// <summary>
///// 821 - 826
///// </summary>
//const uint BCameraPresetStart = 821;
///// <summary>
///// 831
///// </summary>
//const uint BCameraModeAuto = 831;
///// <summary>
///// 832
///// </summary>
//const uint BCameraModeManual = 832;
///// <summary>
///// 833
///// </summary>
//const uint BCameraModeOff = 833;
///// <summary>
///// 841
///// </summary>
//const uint BCameraSelfView = 841;
///// <summary>
///// 842
///// </summary>
//const uint BCameraLayout = 842;
///// <summary>
///// 843
///// </summary>
//const uint BCameraSupportsAutoMode = 843;
///// <summary>
///// 844
///// </summary>
//const uint BCameraSupportsOffMode = 844;
///********* Ushorts *********/
///// <summary>
///// 760
///// </summary>
//const uint UCameraNumberSelect = 760;
///// <summary>
///// 801
///// </summary>
//const uint UDirectorySelectRow = 801;
///// <summary>
///// 801
///// </summary>
//const uint UDirectoryRowCount = 801;
///********* Strings *********/
///// <summary>
///// 701
///// </summary>
//const uint SCurrentDialString = 701;
///// <summary>
///// 702
///// </summary>
//const uint SCurrentCallName = 702;
///// <summary>
///// 703
///// </summary>
//const uint SCurrentCallNumber = 703;
///// <summary>
///// 731
///// </summary>
//const uint SHookState = 731;
///// <summary>
///// 722
///// </summary>
//const uint SCallDirection = 722;
///// <summary>
///// 751
///// </summary>
//const uint SIncomingCallName = 751;
///// <summary>
///// 752
///// </summary>
//const uint SIncomingCallNumber = 752;
///// <summary>
///// 800
///// </summary>
//const uint SDirectorySearchString = 800;
///// <summary>
///// 801-1055
///// </summary>
//const uint SDirectoryEntriesStart = 801;
///// <summary>
///// 1056
///// </summary>
//const uint SDirectoryEntrySelectedName = 1056;
///// <summary>
///// 1057
///// </summary>
//const uint SDirectoryEntrySelectedNumber = 1057;
///// <summary>
///// 1058
///// </summary>
//const uint SDirectorySelectedFolderName = 1058;
///// <summary>
///// 701-712 0-9*#
///// </summary>
//Dictionary<string, uint> DTMFMap = new Dictionary<string, uint>
//{
// { "1", 701 },
// { "2", 702 },
// { "3", 703 },
// { "4", 704 },
// { "5", 705 },
// { "6", 706 },
// { "7", 707 },
// { "8", 708 },
// { "9", 709 },
// { "0", 710 },
// { "*", 711 },
// { "#", 712 },
//};
CodecActiveCallItem CurrentCallItem;
CodecActiveCallItem IncomingCallItem;
ushort PreviousDirectoryLength = 701;
/// <summary>
///
/// </summary>
/// <param name="eisc"></param>
/// <param name="messagePath"></param>
public SIMPLVtcMessenger(string key, BasicTriList eisc, string messagePath)
: base(key, messagePath)
{
EISC = eisc;
JoinMap = new SIMPLVtcJoinMap(701);
CurrentCallItem = new CodecActiveCallItem();
CurrentCallItem.Type = eCodecCallType.Video;
CurrentCallItem.Id = "-video-";
}
/// <summary>
///
/// </summary>
/// <param name="appServerController"></param>
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
var asc = appServerController;
EISC.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
{
CurrentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
PostFullStatus(); // SendCallsList();
});
EISC.SetStringSigAction(JoinMap.CurrentCallNumber.JoinNumber, s =>
{
CurrentCallItem.Number = s;
PostCallsList();
});
EISC.SetStringSigAction(JoinMap.CurrentCallName.JoinNumber, s =>
{
CurrentCallItem.Name = s;
PostCallsList();
});
EISC.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s =>
{
CurrentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
PostCallsList();
});
EISC.SetBoolSigAction(JoinMap.IncomingCall.JoinNumber, b =>
{
if (b)
{
var ica = new CodecActiveCallItem()
{
Direction = eCodecCallDirection.Incoming,
Id = "-video-incoming",
Name = EISC.GetString(JoinMap.IncomingCallName.JoinNumber),
Number = EISC.GetString(JoinMap.IncomingCallNumber.JoinNumber),
Status = eCodecCallStatus.Ringing,
Type = eCodecCallType.Video
};
IncomingCallItem = ica;
}
else
{
IncomingCallItem = null;
}
PostCallsList();
});
EISC.SetBoolSigAction(JoinMap.CameraSupportsAutoMode.JoinNumber, b =>
{
PostStatusMessage(new
{
cameraSupportsAutoMode = b
});
});
EISC.SetBoolSigAction(JoinMap.CameraSupportsOffMode.JoinNumber, b =>
{
PostStatusMessage(new
{
cameraSupportsOffMode = b
});
});
// Directory insanity
EISC.SetUShortSigAction(JoinMap.DirectoryRowCount.JoinNumber, u =>
{
// The length of the list comes in before the list does.
// Splice the sig change operation onto the last string sig that will be changing
// when the directory entries make it through.
if (PreviousDirectoryLength > 0)
{
EISC.ClearStringSigAction(JoinMap.DirectoryEntriesStart.JoinNumber + PreviousDirectoryLength - 1);
}
EISC.SetStringSigAction(JoinMap.DirectoryEntriesStart.JoinNumber + u - 1, s => PostDirectory());
PreviousDirectoryLength = u;
});
EISC.SetStringSigAction(JoinMap.DirectoryEntrySelectedName.JoinNumber, s =>
{
PostStatusMessage(new
{
directoryContactSelected = new
{
name = EISC.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber),
}
});
});
EISC.SetStringSigAction(JoinMap.DirectoryEntrySelectedNumber.JoinNumber, s =>
{
PostStatusMessage(new
{
directoryContactSelected = new
{
number = EISC.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber),
}
});
});
EISC.SetStringSigAction(JoinMap.DirectorySelectedFolderName.JoinNumber, s => PostStatusMessage(new
{
directorySelectedFolderName = EISC.GetString(JoinMap.DirectorySelectedFolderName.JoinNumber)
}));
EISC.SetSigTrueAction(JoinMap.CameraModeAuto.JoinNumber, () => PostCameraMode());
EISC.SetSigTrueAction(JoinMap.CameraModeManual.JoinNumber, () => PostCameraMode());
EISC.SetSigTrueAction(JoinMap.CameraModeOff.JoinNumber, () => PostCameraMode());
EISC.SetBoolSigAction(JoinMap.CameraSelfView.JoinNumber, b => PostStatusMessage(new
{
cameraSelfView = b
}));
EISC.SetUShortSigAction(JoinMap.CameraNumberSelect.JoinNumber, (u) => PostSelectedCamera());
// Add press and holds using helper action
Action<string, uint> addPHAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => EISC.SetBool(u, b)));
addPHAction("/cameraUp", JoinMap.CameraTiltUp.JoinNumber);
addPHAction("/cameraDown", JoinMap.CameraTiltDown.JoinNumber);
addPHAction("/cameraLeft", JoinMap.CameraPanLeft.JoinNumber);
addPHAction("/cameraRight", JoinMap.CameraPanRight.JoinNumber);
addPHAction("/cameraZoomIn", JoinMap.CameraZoomIn.JoinNumber);
addPHAction("/cameraZoomOut", JoinMap.CameraZoomOut.JoinNumber);
// Add straight pulse calls using helper action
Action<string, uint> addAction = (s, u) =>
AppServerController.AddAction(MessagePath + s, new Action(() => EISC.PulseBool(u, 100)));
addAction("/endCallById", JoinMap.EndCall.JoinNumber);
addAction("/endAllCalls", JoinMap.EndCall.JoinNumber);
addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber);
addAction("/rejectById", JoinMap.IncomingReject.JoinNumber);
var speeddialStart = JoinMap.SpeedDialStart.JoinNumber;
var speeddialEnd = JoinMap.SpeedDialStart.JoinNumber + JoinMap.SpeedDialStart.JoinSpan;
var speedDialIndex = 1;
for (uint i = speeddialStart; i < speeddialEnd; i++)
{
addAction(string.Format("/speedDial{0}", speedDialIndex), i);
speedDialIndex++;
}
addAction("/cameraModeAuto", JoinMap.CameraModeAuto.JoinNumber);
addAction("/cameraModeManual", JoinMap.CameraModeManual.JoinNumber);
addAction("/cameraModeOff", JoinMap.CameraModeOff.JoinNumber);
addAction("/cameraSelfView", JoinMap.CameraSelfView.JoinNumber);
addAction("/cameraLayout", JoinMap.CameraLayout.JoinNumber);
asc.AddAction("/cameraSelect", new Action<string>(SelectCamera));
// camera presets
for(uint i = 0; i < 6; i++)
{
addAction("/cameraPreset" + (i + 1), JoinMap.CameraPresetStart.JoinNumber + i);
}
asc.AddAction(MessagePath + "/isReady", new Action(PostIsReady));
// Get status
asc.AddAction(MessagePath + "/fullStatus", new Action(PostFullStatus));
// Dial on string
asc.AddAction(MessagePath + "/dial", new Action<string>(s =>
EISC.SetString(JoinMap.CurrentDialString.JoinNumber, s)));
// Pulse DTMF
AppServerController.AddAction(MessagePath + "/dtmf", new Action<string>(s =>
{
var join = JoinMap.Joins[s];
if (join != null)
{
if (join.JoinNumber > 0)
{
EISC.PulseBool(join.JoinNumber, 100);
}
}
}));
// Directory madness
asc.AddAction(MessagePath + "/directoryRoot", new Action(() => EISC.PulseBool(JoinMap.DirectoryRoot.JoinNumber)));
asc.AddAction(MessagePath + "/directoryBack", new Action(() => EISC.PulseBool(JoinMap.DirectoryFolderBack.JoinNumber)));
asc.AddAction(MessagePath + "/directoryById", new Action<string>(s =>
{
// the id should contain the line number to forward to simpl
try
{
var u = ushort.Parse(s);
EISC.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u);
EISC.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber);
}
catch (Exception)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Warning,
"/directoryById request contains non-numeric ID incompatible with DDVC bridge");
}
}));
asc.AddAction(MessagePath + "/directorySelectContact", new Action<string>(s =>
{
try
{
var u = ushort.Parse(s);
EISC.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u);
EISC.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber);
}
catch
{
}
}));
asc.AddAction(MessagePath + "/directoryDialContact", new Action(() => {
EISC.PulseBool(JoinMap.DirectoryDialSelectedLine.JoinNumber);
}));
asc.AddAction(MessagePath + "/getDirectory", new Action(() =>
{
if (EISC.GetUshort(JoinMap.DirectoryRowCount.JoinNumber) > 0)
{
PostDirectory();
}
else
{
EISC.PulseBool(JoinMap.DirectoryRoot.JoinNumber);
}
}));
}
/// <summary>
///
/// </summary>
void PostFullStatus()
{
this.PostStatusMessage(new
{
calls = GetCurrentCallList(),
cameraMode = GetCameraMode(),
cameraSelfView = EISC.GetBool(JoinMap.CameraSelfView.JoinNumber),
cameraSupportsAutoMode = EISC.GetBool(JoinMap.CameraSupportsAutoMode.JoinNumber),
cameraSupportsOffMode = EISC.GetBool(JoinMap.CameraSupportsOffMode.JoinNumber),
currentCallString = EISC.GetString(JoinMap.CurrentCallNumber.JoinNumber),
currentDialString = EISC.GetString(JoinMap.CurrentDialString.JoinNumber),
directoryContactSelected = new
{
name = EISC.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber),
number = EISC.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber)
},
directorySelectedFolderName = EISC.GetString(JoinMap.DirectorySelectedFolderName.JoinNumber),
isInCall = EISC.GetString(JoinMap.HookState.JoinNumber) == "Connected",
hasDirectory = true,
hasDirectorySearch = false,
hasRecents = !EISC.BooleanOutput[502].BoolValue,
hasCameras = true,
showCamerasWhenNotInCall = EISC.BooleanOutput[503].BoolValue,
selectedCamera = GetSelectedCamera(),
});
}
/// <summary>
///
/// </summary>
void PostDirectory()
{
var u = EISC.GetUshort(JoinMap.DirectoryRowCount.JoinNumber);
var items = new List<object>();
for (uint i = 0; i < u; i++)
{
var name = EISC.GetString(JoinMap.DirectoryEntriesStart.JoinNumber + i);
var id = (i + 1).ToString();
// is folder or contact?
if (name.StartsWith("[+]"))
{
items.Add(new
{
folderId = id,
name = name
});
}
else
{
items.Add(new
{
contactId = id,
name = name
});
}
}
var directoryMessage = new
{
currentDirectory = new
{
isRootDirectory = EISC.GetBool(JoinMap.DirectoryIsRoot.JoinNumber),
directoryResults = items
}
};
PostStatusMessage(directoryMessage);
}
/// <summary>
///
/// </summary>
void PostCameraMode()
{
PostStatusMessage(new
{
cameraMode = GetCameraMode()
});
}
/// <summary>
///
/// </summary>
/// <param name="mode"></param>
string GetCameraMode()
{
string m;
if (EISC.GetBool(JoinMap.CameraModeAuto.JoinNumber)) m = eCameraControlMode.Auto.ToString().ToLower();
else if (EISC.GetBool(JoinMap.CameraModeManual.JoinNumber)) m = eCameraControlMode.Manual.ToString().ToLower();
else m = eCameraControlMode.Off.ToString().ToLower();
return m;
}
void PostSelectedCamera()
{
PostStatusMessage(new
{
selectedCamera = GetSelectedCamera()
});
}
/// <summary>
///
/// </summary>
string GetSelectedCamera()
{
var num = EISC.GetUshort(JoinMap.CameraNumberSelect.JoinNumber);
string m;
if (num == 100)
{
m = "cameraFar";
}
else
{
m = "camera" + num;
}
return m;
}
/// <summary>
///
/// </summary>
void PostIsReady()
{
PostStatusMessage(new
{
isReady = true
});
}
/// <summary>
///
/// </summary>
void PostCallsList()
{
PostStatusMessage(new
{
calls = GetCurrentCallList(),
});
}
/// <summary>
///
/// </summary>
/// <param name="s"></param>
void SelectCamera(string s)
{
var cam = s.Substring(6);
if (cam.ToLower() == "far")
{
EISC.SetUshort(JoinMap.CameraNumberSelect.JoinNumber, 100);
}
else
{
EISC.SetUshort(JoinMap.CameraNumberSelect.JoinNumber, UInt16.Parse(cam));
}
}
/// <summary>
/// Turns the
/// </summary>
/// <returns></returns>
List<CodecActiveCallItem> GetCurrentCallList()
{
var list = new List<CodecActiveCallItem>();
if (CurrentCallItem.Status != eCodecCallStatus.Disconnected)
{
list.Add(CurrentCallItem);
}
if (EISC.GetBool(JoinMap.IncomingCall.JoinNumber))
{
}
return list;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Bridges;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Properties to configure a SIMPL Messenger
/// </summary>
public class SimplMessengerPropertiesConfig : EiscApiPropertiesConfig.ApiDevicePropertiesConfig
{
}
}

View File

@@ -0,0 +1,86 @@
using System;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core.Monitoring;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SystemMonitorMessenger : MessengerBase
{
public SystemMonitorController SysMon { get; private set; }
public SystemMonitorMessenger(string key, SystemMonitorController sysMon, string messagePath)
: base(key, messagePath)
{
if (sysMon == null)
throw new ArgumentNullException("sysMon");
SysMon = sysMon;
SysMon.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged;
foreach (var p in SysMon.ProgramStatusFeedbackCollection)
{
p.Value.ProgramInfoChanged += ProgramInfoChanged;
}
CrestronConsole.AddNewConsoleCommand(s => SendFullStatusMessage(), "SendFullSysMonStatus", "Sends the full System Monitor Status", ConsoleAccessLevelEnum.AccessOperator);
}
/// <summary>
/// Posts the program information message
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ProgramInfoChanged(object sender, ProgramInfoEventArgs e)
{
if (e.ProgramInfo != null)
{
//Debug.Console(1, "Posting Status Message: {0}", e.ProgramInfo.ToString());
PostStatusMessage(e.ProgramInfo);
}
}
/// <summary>
/// Posts the system monitor properties
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void SysMon_SystemMonitorPropertiesChanged(object sender, EventArgs e)
{
SendSystemMonitorStatusMessage();
}
void SendFullStatusMessage()
{
SendSystemMonitorStatusMessage();
foreach (var p in SysMon.ProgramStatusFeedbackCollection)
{
PostStatusMessage(p.Value.ProgramInfo);
}
}
void SendSystemMonitorStatusMessage()
{
Debug.Console(1, "Posting System Monitor Status Message.");
// This takes a while, launch a new thread
CrestronInvoke.BeginInvoke(o => PostStatusMessage(new
{
timeZone = SysMon.TimeZoneFeedback.IntValue,
timeZoneName = SysMon.TimeZoneTextFeedback.StringValue,
ioControllerVersion = SysMon.IoControllerVersionFeedback.StringValue,
snmpVersion = SysMon.SnmpVersionFeedback.StringValue,
bacnetVersion = SysMon.BaCnetAppVersionFeedback.StringValue,
controllerVersion = SysMon.ControllerVersionFeedback.StringValue
}));
}
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatusMessage));
}
}
}

View File

@@ -0,0 +1,596 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.AppServer.Messengers
{
/// <summary>
/// Provides a messaging bridge for a VideoCodecBase device
/// </summary>
public class VideoCodecBaseMessenger : MessengerBase
{
/// <summary>
///
/// </summary>
public VideoCodecBase Codec { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="codec"></param>
public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
: base(key, messagePath)
{
if (codec == null)
throw new ArgumentNullException("codec");
Codec = codec;
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
codec.IsReadyChange += new EventHandler<EventArgs>(codec_IsReadyChange);
var dirCodec = codec as IHasDirectory;
if (dirCodec != null)
{
dirCodec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dirCodec_DirectoryResultReturned);
}
var recCodec = codec as IHasCallHistory;
if (recCodec != null)
{
recCodec.CallHistory.RecentCallsListHasChanged += new EventHandler<EventArgs>(CallHistory_RecentCallsListHasChanged);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
{
var recents = (sender as CodecCallHistory).RecentCalls;
if (recents != null)
{
PostStatusMessage(new
{
recentCalls = recents
});
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void dirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{
SendDirectory((Codec as IHasDirectory).CurrentDirectoryResult, e.DirectoryIsOnRoot);
}
/// <summary>
/// Posts the current directory
/// </summary>
void SendDirectory(CodecDirectory directory, bool isRoot)
{
var dirCodec = Codec as IHasDirectory;
if (dirCodec != null)
{
var prefixedDirectoryResults = PrefixDirectoryFolderItems(directory);
var directoryMessage = new
{
currentDirectory = new
{
directoryResults = prefixedDirectoryResults,
isRootDirectory = isRoot
}
};
PostStatusMessage(directoryMessage);
}
}
/// <summary>
/// Iterates a directory object and prefixes any folder items with "[+] "
/// </summary>
/// <param name="directory"></param>
/// <returns></returns>
List<DirectoryItem> PrefixDirectoryFolderItems (CodecDirectory directory)
{
var tempDirectoryList = new List<DirectoryItem>();
if (directory.CurrentDirectoryResults.Count > 0)
{
foreach (var item in directory.CurrentDirectoryResults)
{
if (item is DirectoryFolder)
{
var newFolder = new DirectoryFolder();
newFolder = (DirectoryFolder)item.Clone();
string prefixName = "[+] " + newFolder.Name;
newFolder.Name = prefixName;
tempDirectoryList.Add(newFolder);
}
else
{
tempDirectoryList.Add(item);
}
}
}
//else
//{
// DirectoryItem noResults = new DirectoryItem() { Name = "No Results Found" };
// tempDirectoryList.Add(noResults);
//}
return tempDirectoryList;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void codec_IsReadyChange(object sender, EventArgs e)
{
PostStatusMessage(new
{
isReady = true
});
}
/// <summary>
/// Called from base's RegisterWithAppServer method
/// </summary>
/// <param name="appServerController"></param>
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
{
appServerController.AddAction("/device/videoCodec/isReady", new Action(SendIsReady));
appServerController.AddAction("/device/videoCodec/fullStatus", new Action(SendVtcFullMessageObject));
appServerController.AddAction("/device/videoCodec/dial", new Action<string>(s => Codec.Dial(s)));
appServerController.AddAction("/device/videoCodec/endCallById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.EndCall(call);
}));
appServerController.AddAction(MessagePath + "/endAllCalls", new Action(Codec.EndAllCalls));
appServerController.AddAction(MessagePath + "/dtmf", new Action<string>(s => Codec.SendDtmf(s)));
appServerController.AddAction(MessagePath + "/rejectById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.RejectCall(call);
}));
appServerController.AddAction(MessagePath + "/acceptById", new Action<string>(s =>
{
var call = GetCallWithId(s);
if (call != null)
Codec.AcceptCall(call);
}));
// Directory actions
var dirCodec = Codec as IHasDirectory;
if (dirCodec != null)
{
appServerController.AddAction(MessagePath + "/getDirectory", new Action(GetDirectoryRoot));
appServerController.AddAction(MessagePath + "/directoryById", new Action<string>(s => GetDirectory(s)));
appServerController.AddAction(MessagePath + "/directorySearch", new Action<string>(s => DirectorySearch(s)));
appServerController.AddAction(MessagePath + "/directoryBack", new Action(GetPreviousDirectory));
}
// History actions
var recCodec = Codec as IHasCallHistory;
if (recCodec != null)
{
appServerController.AddAction(MessagePath + "/getCallHistory", new Action(GetCallHistory));
}
var cameraCodec = Codec as IHasCodecCameras;
if (cameraCodec != null)
{
Debug.Console(2, this, "Adding IHasCodecCameras Actions");
cameraCodec.CameraSelected += new EventHandler<CameraSelectedEventArgs>(cameraCodec_CameraSelected);
appServerController.AddAction(MessagePath + "/cameraSelect", new Action<string>(s => cameraCodec.SelectCamera(s)));
MapCameraActions();
var presetsCodec = Codec as IHasCodecRoomPresets;
if (presetsCodec != null)
{
Debug.Console(2, this, "Adding IHasCodecRoomPresets Actions");
presetsCodec.CodecRoomPresetsListHasChanged += new EventHandler<EventArgs>(presetsCodec_CameraPresetsListHasChanged);
appServerController.AddAction(MessagePath + "/cameraPreset", new Action<int>(u => presetsCodec.CodecRoomPresetSelect(u)));
appServerController.AddAction(MessagePath + "/cameraPresetStore", new Action<CodecRoomPreset>(p => presetsCodec.CodecRoomPresetStore(p.ID, p.Description)));
}
var speakerTrackCodec = Codec as IHasCameraAutoMode;
if (speakerTrackCodec != null)
{
Debug.Console(2, this, "Adding IHasCameraAutoMode Actions");
speakerTrackCodec.CameraAutoModeIsOnFeedback.OutputChange += new EventHandler<PepperDash.Essentials.Core.FeedbackEventArgs>(CameraAutoModeIsOnFeedback_OutputChange);
appServerController.AddAction(MessagePath + "/cameraAuto", new Action(speakerTrackCodec.CameraAutoModeOn));
appServerController.AddAction(MessagePath + "/cameraManual", new Action(speakerTrackCodec.CameraAutoModeOff));
}
}
var selfViewCodec = Codec as IHasCodecSelfView;
if (selfViewCodec != null)
{
Debug.Console(2, this, "Adding IHasCodecSelfView Actions");
appServerController.AddAction(MessagePath + "/cameraSelfView", new Action(selfViewCodec.SelfViewModeToggle));
}
var layoutsCodec = Codec as IHasCodecLayouts;
if (layoutsCodec != null)
{
Debug.Console(2, this, "Adding IHasCodecLayouts Actions");
appServerController.AddAction(MessagePath + "/cameraRemoteView", new Action(layoutsCodec.LocalLayoutToggle));
}
Debug.Console(2, this, "Adding Privacy & Standby Actions");
appServerController.AddAction(MessagePath + "/privacyModeOn", new Action(Codec.PrivacyModeOn));
appServerController.AddAction(MessagePath + "/privacyModeOff", new Action(Codec.PrivacyModeOff));
appServerController.AddAction(MessagePath + "/privacyModeToggle", new Action(Codec.PrivacyModeToggle));
appServerController.AddAction(MessagePath + "/sharingStart", new Action(Codec.StartSharing));
appServerController.AddAction(MessagePath + "/sharingStop", new Action(Codec.StopSharing));
appServerController.AddAction(MessagePath + "/standbyOn", new Action(Codec.StandbyActivate));
appServerController.AddAction(MessagePath + "/standbyOff", new Action(Codec.StandbyDeactivate));
}
void presetsCodec_CameraPresetsListHasChanged(object sender, EventArgs e)
{
PostCameraPresets();
}
void CameraAutoModeIsOnFeedback_OutputChange(object sender, PepperDash.Essentials.Core.FeedbackEventArgs e)
{
PostCameraMode();
}
void cameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e)
{
MapCameraActions();
PostSelectedCamera();
}
/// <summary>
/// Maps the camera control actions to the current selected camera on the codec
/// </summary>
void MapCameraActions()
{
var cameraCodec = Codec as IHasCameras;
if (cameraCodec != null && cameraCodec.SelectedCamera != null)
{
AppServerController.RemoveAction(MessagePath + "/cameraUp");
AppServerController.RemoveAction(MessagePath + "/cameraDown");
AppServerController.RemoveAction(MessagePath + "/cameraLeft");
AppServerController.RemoveAction(MessagePath + "/cameraRight");
AppServerController.RemoveAction(MessagePath + "/cameraZoomIn");
AppServerController.RemoveAction(MessagePath + "/cameraZoomOut");
AppServerController.RemoveAction(MessagePath + "/cameraHome");
var camera = cameraCodec.SelectedCamera as IHasCameraPtzControl;
if (camera != null)
{
AppServerController.AddAction(MessagePath + "/cameraUp", new PressAndHoldAction(new Action<bool>(b => { if (b)camera.TiltUp(); else camera.TiltStop(); })));
AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction(new Action<bool>(b => { if (b)camera.TiltDown(); else camera.TiltStop(); })));
AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction(new Action<bool>(b => { if (b)camera.PanLeft(); else camera.PanStop(); })));
AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction(new Action<bool>(b => { if (b)camera.PanRight(); else camera.PanStop(); })));
AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction(new Action<bool>(b => { if (b)camera.ZoomIn(); else camera.ZoomStop(); })));
AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction(new Action<bool>(b => { if (b)camera.ZoomOut(); else camera.ZoomStop(); })));
AppServerController.AddAction(MessagePath + "/cameraHome", new Action(camera.PositionHome));
var focusCamera = cameraCodec as IHasCameraFocusControl;
AppServerController.RemoveAction(MessagePath + "/cameraAutoFocus");
AppServerController.RemoveAction(MessagePath + "/cameraFocusNear");
AppServerController.RemoveAction(MessagePath + "/cameraFocusFar");
if (focusCamera != null)
{
AppServerController.AddAction(MessagePath + "/cameraAutoFocus", new Action(focusCamera.TriggerAutoFocus));
AppServerController.AddAction(MessagePath + "/cameraFocusNear", new PressAndHoldAction(new Action<bool>(b => { if (b)focusCamera.FocusNear(); else focusCamera.FocusStop(); })));
AppServerController.AddAction(MessagePath + "/cameraFocusFar", new PressAndHoldAction(new Action<bool>(b => { if (b)focusCamera.FocusFar(); else focusCamera.FocusStop(); })));
}
}
}
}
string GetCameraMode()
{
string m = "";
var speakerTrackCodec = Codec as IHasCameraAutoMode;
if (speakerTrackCodec != null)
{
if (speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue) m = eCameraControlMode.Auto.ToString();
else m = eCameraControlMode.Manual.ToString();
}
var cameraOffCodec = Codec as IHasCameraOff;
if (cameraOffCodec != null)
{
if (cameraOffCodec.CameraIsOffFeedback.BoolValue)
m = eCameraControlMode.Off.ToString();
}
return m;
}
void GetCallHistory()
{
var codec = (Codec as IHasCallHistory);
if (codec != null)
{
var recents = codec.CallHistory.RecentCalls;
if (recents != null)
{
PostStatusMessage(new
{
recentCalls = recents
});
}
}
}
public void GetFullStatusMessage()
{
}
/// <summary>
/// Helper to grab a call with string ID
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
CodecActiveCallItem GetCallWithId(string id)
{
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
}
/// <summary>
///
/// </summary>
/// <param name="s"></param>
void DirectorySearch(string s)
{
var dirCodec = Codec as IHasDirectory;
if (dirCodec != null)
{
dirCodec.SearchDirectory(s);
}
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
void GetDirectory(string id)
{
var dirCodec = Codec as IHasDirectory;
if(dirCodec == null)
{
return;
}
dirCodec.GetDirectoryFolderContents(id);
}
/// <summary>
///
/// </summary>
void GetDirectoryRoot()
{
var dirCodec = Codec as IHasDirectory;
if (dirCodec == null)
{
// do something else?
return;
}
if (!dirCodec.PhonebookSyncState.InitialSyncComplete)
{
PostStatusMessage(new
{
initialSyncComplete = false
});
return;
}
dirCodec.SetCurrentDirectoryToRoot();
//PostStatusMessage(new
//{
// currentDirectory = dirCodec.DirectoryRoot
//});
}
/// <summary>
/// Requests the parent folder contents
/// </summary>
void GetPreviousDirectory()
{
var dirCodec = Codec as IHasDirectory;
if (dirCodec == null)
{
return;
}
dirCodec.GetDirectoryParentFolderContents();
}
/// <summary>
/// Handler for codec changes
/// </summary>
void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
SendVtcFullMessageObject();
}
/// <summary>
///
/// </summary>
void SendIsReady()
{
PostStatusMessage(new
{
isReady = Codec.IsReady
});
}
/// <summary>
/// Helper method to build call status for vtc
/// </summary>
/// <returns></returns>
void SendVtcFullMessageObject()
{
if (!Codec.IsReady)
{
return;
}
object cameraInfo = null;
var camerasCodec = Codec as IHasCodecCameras;
if (camerasCodec != null)
{
cameraInfo = new
{
cameraManualSupported = true, // For now, we assume manual mode is supported and selectively hide controls based on camera selection
cameraAutoSupported = Codec is IHasCameraAutoMode,
cameraOffSupported = Codec is IHasCameraOff,
cameraMode = GetCameraMode(),
cameraList = camerasCodec.Cameras,
selectedCamera = GetSelectedCamera(camerasCodec)
};
}
var info = Codec.CodecInfo;
PostStatusMessage(new
{
isInCall = Codec.IsInCall,
privacyModeIsOn = Codec.PrivacyModeIsOnFeedback.BoolValue,
sharingContentIsOn = Codec.SharingContentIsOnFeedback.BoolValue,
sharingSource = Codec.SharingSourceFeedback.StringValue,
standbyIsOn = Codec.StandbyIsOnFeedback.StringValue,
calls = Codec.ActiveCalls,
info = new
{
autoAnswerEnabled = info.AutoAnswerEnabled,
e164Alias = info.E164Alias,
h323Id = info.H323Id,
ipAddress = info.IpAddress,
sipPhoneNumber = info.SipPhoneNumber,
sipURI = info.SipUri
},
showSelfViewByDefault = Codec.ShowSelfViewByDefault,
hasDirectory = Codec is IHasDirectory,
hasDirectorySearch = true,
hasRecents = Codec is IHasCallHistory,
hasCameras = Codec is IHasCameras,
cameras = cameraInfo,
presets = GetCurrentPresets()
});
}
/// <summary>
///
/// </summary>
void PostCameraMode()
{
PostStatusMessage(new
{
cameras = new
{
cameraMode = GetCameraMode()
}
});
}
void PostSelectedCamera()
{
var camerasCodec = Codec as IHasCodecCameras;
PostStatusMessage(new
{
cameras = new
{
selectedCamera = GetSelectedCamera(camerasCodec)
},
presets = GetCurrentPresets()
});
}
void PostCameraPresets()
{
PostStatusMessage(new
{
presets = GetCurrentPresets()
});
}
object GetSelectedCamera(IHasCodecCameras camerasCodec)
{
return new
{
key = camerasCodec.SelectedCameraFeedback.StringValue,
isFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue,
capabilites = new
{
canPan = camerasCodec.SelectedCamera.CanPan,
canTilt = camerasCodec.SelectedCamera.CanTilt,
canZoom = camerasCodec.SelectedCamera.CanZoom,
canFocus = camerasCodec.SelectedCamera.CanFocus
}
};
}
List<CodecRoomPreset> GetCurrentPresets()
{
var presetsCodec = Codec as IHasCodecRoomPresets;
List<CodecRoomPreset> currentPresets = null;
if (presetsCodec != null && Codec is IHasFarEndCameraControl && (Codec as IHasFarEndCameraControl).ControllingFarEndCameraFeedback.BoolValue)
currentPresets = presetsCodec.FarEndRoomPresets;
else
currentPresets = presetsCodec.NearEndPresets;
return currentPresets;
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core.Config;
using Newtonsoft.Json;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class MobileControlConfig
{
[JsonProperty("serverUrl")]
public string ServerUrl { get; set; }
[JsonProperty("clientAppUrl")]
public string ClientAppUrl { get; set; }
}
/// <summary>
///
/// </summary>
public class MobileControlDdvc01RoomBridgePropertiesConfig
{
[JsonProperty("eiscId")]
public string EiscId { get; set; }
}
}

View File

@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Room.MobileControl
{
/// <summary>
/// Represents a generic device connection through to and EISC for DDVC01
/// </summary>
public class MobileControlDdvc01DeviceBridge : Device, IChannel, INumericKeypad
{
/// <summary>
/// EISC used to talk to Simpl
/// </summary>
ThreeSeriesTcpIpEthernetIntersystemCommunications EISC;
public MobileControlDdvc01DeviceBridge(string key, string name, ThreeSeriesTcpIpEthernetIntersystemCommunications eisc)
: base(key, name)
{
EISC = eisc;
}
#region IChannel Members
public void ChannelUp(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void ChannelDown(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void LastChannel(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Guide(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Info(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Exit(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
#endregion
#region INumericKeypad Members
public void Digit0(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit1(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit2(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit3(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit4(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit5(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit6(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit7(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit8(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public void Digit9(bool pressRelease)
{
EISC.SetBool(1111, pressRelease);
}
public bool HasKeypadAccessoryButton1
{
get { throw new NotImplementedException(); }
}
public string KeypadAccessoryButton1Label
{
get { throw new NotImplementedException(); }
}
public void KeypadAccessoryButton1(bool pressRelease)
{
throw new NotImplementedException();
}
public bool HasKeypadAccessoryButton2
{
get { throw new NotImplementedException(); }
}
public string KeypadAccessoryButton2Label
{
get { throw new NotImplementedException(); }
}
public void KeypadAccessoryButton2(bool pressRelease)
{
throw new NotImplementedException();
}
#endregion
}
}

View File

@@ -0,0 +1,884 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro.CrestronThread;
using Crestron.SimplSharp.CrestronWebSocketClient;
using Crestron.SimplSharpPro;
using Crestron.SimplSharp.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.MobileControl;
using PepperDash.Essentials.AppServer.Messengers;
namespace PepperDash.Essentials
{
public class MobileControlSystemController : EssentialsDevice
{
WebSocketClient WSClient;
//bool LinkUp;
/// <summary>
/// Prevents post operations from stomping on each other and getting lost
/// </summary>
CEvent PostLockEvent = new CEvent(true, true);
CEvent RegisterLockEvent = new CEvent(true, true);
public MobileControlConfig Config { get; private set; }
Dictionary<string, Object> ActionDictionary = new Dictionary<string, Object>(StringComparer.InvariantCultureIgnoreCase);
Dictionary<string, CTimer> PushedActions = new Dictionary<string, CTimer>();
public ConfigMessenger ConfigMessenger { get; private set; }
CTimer ServerHeartbeatCheckTimer;
long ServerHeartbeatInterval = 20000;
CTimer ServerReconnectTimer;
long ServerReconnectInterval = 5000;
DateTime LastAckMessage;
public string SystemUuid;
List<MobileControlBridgeBase> RoomBridges = new List<MobileControlBridgeBase>();
long ButtonHeartbeatInterval = 1000;
/// <summary>
/// Used for tracking HTTP debugging
/// </summary>
bool HttpDebugEnabled;
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="config"></param>
public MobileControlSystemController(string key, string name, MobileControlConfig config) : base(key, name)
{
Config = config;
SystemUuid = ConfigReader.ConfigObject.SystemUuid;
Debug.Console(0, this, "Mobile UI controller initializing for server:{0}", config.ServerUrl);
CrestronConsole.AddNewConsoleCommand(AuthorizeSystem,
"mobileauth", "Authorizes system to talk to Mobile Control server", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => ShowInfo(),
"mobileinfo", "Shows information for current mobile control session", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => {
s = s.Trim();
if(!string.IsNullOrEmpty(s))
{
HttpDebugEnabled = (s.Trim() != "0");
}
CrestronConsole.ConsoleCommandResponse("HTTP Debug {0}", HttpDebugEnabled ? "Enabled" : "Disabled");
},
"mobilehttpdebug", "1 enables more verbose HTTP response debugging", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(TestHttpRequest,
"mobilehttprequest", "Tests an HTTP get to URL given", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(PrintActionDictionaryPaths, "mobileshowactionpaths",
"Prints the paths in the Action Dictionary", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => ConnectWebsocketClient(), "mobileconnect",
"Forces connect of websocket", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CleanUpWebsocketClient(), "mobiledisco",
"Disconnects websocket", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => ParseStreamRx(s), "mobilesimulateaction", "Simulates a message from the server", ConsoleAccessLevelEnum.AccessOperator);
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler);
// Config Messenger
var cmKey = Key + "-config";
ConfigMessenger = new ConfigMessenger(cmKey, "/config");
ConfigMessenger.RegisterWithAppServer(this);
}
/// <summary>
/// If config rooms is empty or null then go
/// </summary>
/// <returns></returns>
public override bool CustomActivate()
{
if (ConfigReader.ConfigObject.Rooms == null || ConfigReader.ConfigObject.Rooms.Count == 0)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Config contains no rooms. Registering with Server.");
RegisterSystemToServer();
}
return base.CustomActivate();
}
/// <summary>
///
/// </summary>
/// <param name="ethernetEventArgs"></param>
void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs args)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Ethernet status change, port {0}: {1}",
args.EthernetAdapter, args.EthernetEventType);
if (args.EthernetEventType == eEthernetEventType.LinkDown && WSClient != null && args.EthernetAdapter == WSClient.EthernetAdapter)
{
CleanUpWebsocketClient();
}
}
/// <summary>
/// Sends message to server to indicate the system is shutting down
/// </summary>
/// <param name="programEventType"></param>
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{
if (programEventType == eProgramStatusEventType.Stopping
&& WSClient != null
&& WSClient.Connected)
{
CleanUpWebsocketClient();
}
}
public void PrintActionDictionaryPaths(object o)
{
Debug.Console(0, this, "ActionDictionary Contents:");
foreach (var item in ActionDictionary)
{
Debug.Console(0, this, "{0}", item.Key);
}
}
/// <summary>
/// Adds an action to the dictionary
/// </summary>
/// <param name="key">The path of the API command</param>
/// <param name="action">The action to be triggered by the commmand</param>
public void AddAction(string key, object action)
{
if (!ActionDictionary.ContainsKey(key))
{
ActionDictionary.Add(key, action);
}
else
{
Debug.Console(1, this, "Cannot add action with key '{0}' because key already exists in ActionDictionary.", key);
}
}
/// <summary>
/// Removes an action from the dictionary
/// </summary>
/// <param name="key"></param>
public void RemoveAction(string key)
{
if (ActionDictionary.ContainsKey(key))
ActionDictionary.Remove(key);
}
/// <summary>
///
/// </summary>
/// <param name="bridge"></param>
public void AddBridge(MobileControlBridgeBase bridge)
{
RoomBridges.Add(bridge);
var b = bridge as IDelayedConfiguration;
if (b != null)
{
Debug.Console(0, this, "Adding room bridge with delayed configuration");
b.ConfigurationIsReady += new EventHandler<EventArgs>(bridge_ConfigurationIsReady);
}
else
{
Debug.Console(0, this, "Adding room bridge and sending configuration");
//SystemUuid = ConfigReader.ConfigObject.SystemUuid;
RegisterSystemToServer();
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void bridge_ConfigurationIsReady(object sender, EventArgs e)
{
Debug.Console(1, this, "Bridge ready. Registering");
//SystemUuid = ConfigReader.ConfigObject.SystemUuid;
// send the configuration object to the server
RegisterSystemToServer();
}
/// <summary>
///
/// </summary>
/// <param name="o"></param>
void ReconnectToServerTimerCallback(object o)
{
RegisterSystemToServer();
}
/// <summary>
/// Verifies system connection with servers
/// </summary>
/// <param name="command"></param>
void AuthorizeSystem(string code)
{
//SystemUuid = ConfigReader.ConfigObject.SystemUuid;
if (string.IsNullOrEmpty(SystemUuid))
{
CrestronConsole.ConsoleCommandResponse("System does not have a UUID. Please ensure proper portal-format configuration is loaded and restart.");
return;
}
if (string.IsNullOrEmpty(code))
{
CrestronConsole.ConsoleCommandResponse("Please enter a user code to authorize a system");
return;
}
var req = new HttpClientRequest();
string url = string.Format("http://{0}/api/system/grantcode/{1}/{2}", Config.ServerUrl, code, SystemUuid);
Debug.Console(0, this, "Authorizing to: {0}", url);
if (string.IsNullOrEmpty(Config.ServerUrl))
{
CrestronConsole.ConsoleCommandResponse("Config URL address is not set. Check portal configuration");
return;
}
try
{
req.Url.Parse(url);
new HttpClient().DispatchAsync(req, (r, e) =>
{
CheckHttpDebug(r, e);
if (e == HTTP_CALLBACK_ERROR.COMPLETED)
{
if (r.Code == 200)
{
Debug.Console(0, "System authorized, sending config.");
#warning This registration may need to wait for config ready. Maybe.
RegisterSystemToServer();
}
else if (r.Code == 404)
{
if (r.ContentString.Contains("codeNotFound"))
{
Debug.Console(0, "Authorization failed, code not found for system UUID {0}", SystemUuid);
}
else if (r.ContentString.Contains("uuidNotFound"))
{
Debug.Console(0, "Authorization failed, uuid {0} not found. Check Essentials configuration is correct",
SystemUuid);
}
}
else
{
Debug.Console(0, "Authorization failed, code {0}: {1}", r.Code, r.ContentString);
}
}
else
Debug.Console(0, this, "Error {0} in authorizing system", e);
});
}
catch (Exception e)
{
Debug.Console(0, this, "Error in authorizing: {0}", e);
}
}
/// <summary>
/// Dumps info in response to console command.
/// </summary>
void ShowInfo()
{
var url = Config != null ? Config.ServerUrl : "No config";
string name;
string code;
if (RoomBridges != null && RoomBridges.Count > 0)
{
name = RoomBridges[0].RoomName;
code = RoomBridges[0].UserCode;
}
else
{
name = "No config";
code = "Not available";
}
var conn = WSClient == null ? "No client" : (WSClient.Connected ? "Yes" : "No");
var secSinceLastAck = DateTime.Now - LastAckMessage;
CrestronConsole.ConsoleCommandResponse(@"Mobile Control Information:
Server address: {0}
System Name: {1}
System URL: {2}
System UUID: {3}
System User code: {4}
Connected?: {5}
Seconds Since Last Ack: {6}"
, url, name, ConfigReader.ConfigObject.SystemUrl, SystemUuid,
code, conn, secSinceLastAck.Seconds);
}
/// <summary>
/// Registers the room with the server
/// </summary>
/// <param name="url">URL of the server, including the port number, if not 80. Format: "serverUrlOrIp:port"</param>
void RegisterSystemToServer()
{
ConnectWebsocketClient();
}
/// <summary>
/// Connects the Websocket Client
/// </summary>
/// <param name="o"></param>
void ConnectWebsocketClient()
{
Debug.Console(1, this, "Initializing Stream client to server.");
if (WSClient != null)
{
Debug.Console(1, this, "Cleaning up previous socket");
CleanUpWebsocketClient();
}
WSClient = new WebSocketClient();
WSClient.URL = string.Format("wss://{0}/system/join/{1}", Config.ServerUrl, this.SystemUuid);
WSClient.ConnectionCallBack = Websocket_ConnectCallback;
WSClient.ConnectAsync();
}
/// <summary>
///
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
int Websocket_ConnectCallback(WebSocketClient.WEBSOCKET_RESULT_CODES code)
{
if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
{
StopServerReconnectTimer();
Debug.Console(1, this, "Websocket connected");
WSClient.DisconnectCallBack = Websocket_DisconnectCallback;
WSClient.SendCallBack = Websocket_SendCallback;
WSClient.ReceiveCallBack = Websocket_ReceiveCallback;
WSClient.ReceiveAsync();
SendMessageObjectToServer(new
{
type = "hello"
});
}
else
{
if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_HTTP_HANDSHAKE_TOKEN_ERROR)
{
// This is the case when app server is running behind a websever and app server is down
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failed. Check that app server is running behind web server");
}
else if (code == WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SOCKET_CONNECTION_FAILED)
{
// this will be the case when webserver is unreachable
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failed");
}
else
{
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Web socket connection failure: {0}", code);
}
StartServerReconnectTimer();
}
return 0;
}
/// <summary>
/// After a "hello" from the server, sends config and stuff
/// </summary>
void SendInitialMessage()
{
Debug.Console(1, this, "Sending initial join message");
var confObject = ConfigReader.ConfigObject;
confObject.Info.RuntimeInfo.AppName = Assembly.GetExecutingAssembly().GetName().Name;
var version = Assembly.GetExecutingAssembly().GetName().Version;
confObject.Info.RuntimeInfo.AssemblyVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
var msg = new
{
type = "join",
content = new
{
config = confObject
}
};
SendMessageObjectToServer(msg);
}
/// <summary>
/// Sends any object type to server
/// </summary>
/// <param name="o"></param>
public void SendMessageObjectToServer(object o)
{
SendMessageToServer(JObject.FromObject(o));
}
/// <summary>
/// Sends a message to the server from a room
/// </summary>
/// <param name="room">room from which the message originates</param>
/// <param name="o">object to be serialized and sent in post body</param>
public void SendMessageToServer(JObject o)
{
if (WSClient != null && WSClient.Connected)
{
string message = JsonConvert.SerializeObject(o, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
if (!message.Contains("/system/heartbeat"))
Debug.Console(1, this, "Message TX: {0}", message);
//else
// Debug.Console(1, this, "TX messages contains /system/heartbeat");
var messageBytes = System.Text.Encoding.UTF8.GetBytes(message);
var result = WSClient.Send(messageBytes, (uint)messageBytes.Length, WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME);
if (result != WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
{
Debug.Console(1, this, "Socket send result error: {0}", result);
}
}
else if (WSClient == null)
{
Debug.Console(1, this, "Cannot send. Not connected.");
}
}
/// <summary>
/// Disconnects the SSE Client and stops the heartbeat timer
/// </summary>
/// <param name="command"></param>
void CleanUpWebsocketClient()
{
Debug.Console(1, this, "Disconnecting websocket");
if (WSClient != null)
{
WSClient.SendCallBack = null;
WSClient.ReceiveCallBack = null;
WSClient.ConnectionCallBack = null;
WSClient.DisconnectCallBack = null;
if (WSClient.Connected)
{
WSClient.Disconnect();
}
WSClient = null;
}
}
/// <summary>
///
/// </summary>
/// <param name="dueTime"></param>
/// <param name="repeatTime"></param>
void StartServerReconnectTimer()
{
StopServerReconnectTimer();
ServerReconnectTimer = new CTimer(ReconnectToServerTimerCallback, ServerReconnectInterval);
Debug.Console(1, this, "Reconnect Timer Started.");
}
/// <summary>
/// Does what it says
/// </summary>
void StopServerReconnectTimer()
{
if (ServerReconnectTimer != null)
{
ServerReconnectTimer.Stop();
ServerReconnectTimer = null;
}
}
/// <summary>
/// Executes when we don't get a heartbeat message in time. Triggers reconnect.
/// </summary>
/// <param name="o">For CTimer callback. Not used</param>
void HeartbeatExpiredTimerCallback(object o)
{
Debug.Console(1, this, "Heartbeat Timer Expired.");
if (ServerHeartbeatCheckTimer != null)
{
ServerHeartbeatCheckTimer.Stop();
ServerHeartbeatCheckTimer = null;
}
CleanUpWebsocketClient();
StartServerReconnectTimer();
}
/// <summary>
///
/// </summary>
/// <param name="dueTime"></param>
/// <param name="repeatTime"></param>
void ResetOrStartHearbeatTimer()
{
if (ServerHeartbeatCheckTimer == null)
{
ServerHeartbeatCheckTimer = new CTimer(HeartbeatExpiredTimerCallback, null, ServerHeartbeatInterval, ServerHeartbeatInterval);
Debug.Console(1, this, "Heartbeat Timer Started.");
}
else
{
ServerHeartbeatCheckTimer.Reset(ServerHeartbeatInterval, ServerHeartbeatInterval);
}
}
/// <summary>
/// Waits two and goes again
/// </summary>
void ReconnectStreamClient()
{
new CTimer(o => ConnectWebsocketClient(), 2000);
}
/// <summary>
///
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
int Websocket_DisconnectCallback(WebSocketClient.WEBSOCKET_RESULT_CODES code, object o)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Warning, "Websocket disconnected with code: {0}", code);
if (ServerHeartbeatCheckTimer != null)
ServerHeartbeatCheckTimer.Stop();
// Start the reconnect timer
StartServerReconnectTimer();
return 0;
}
/// <summary>
/// Resets reconnect timer and updates usercode
/// </summary>
/// <param name="content"></param>
void HandleHeartBeat(JToken content)
{
SendMessageToServer(JObject.FromObject(new
{
type = "/system/heartbeatAck"
}));
var code = content["userCode"];
if(code != null)
{
foreach (var b in RoomBridges)
{
b.SetUserCode(code.Value<string>());
}
}
ResetOrStartHearbeatTimer();
}
/// <summary>
/// Outputs debug info when enabled
/// </summary>
/// <param name="req"></param>
/// <param name="r"></param>
/// <param name="e"></param>
void CheckHttpDebug(HttpClientResponse r, HTTP_CALLBACK_ERROR e)
{
if (HttpDebugEnabled)
{
try
{
Debug.Console(0, this, "------ Begin HTTP Debug ---------------------------------------");
if (r != null)
{
Debug.Console(0, this, "HTTP Response URL: {0}", r.ResponseUrl != null ? r.ResponseUrl.ToString() : "NONE");
Debug.Console(0, this, "HTTP Response code: {0}", r.Code);
Debug.Console(0, this, "HTTP Response content: \r{0}", r.ContentString);
}
else
{
Debug.Console(0, this, "No HTTP response");
}
Debug.Console(0, this, "HTTP Response 'error' {0}", e);
Debug.Console(0, this, "------ End HTTP Debug -----------------------------------------");
}
catch (Exception ex)
{
Debug.Console(0, this, "HttpDebugError: {0}", ex);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <param name="opcode"></param>
/// <param name="err"></param>
int Websocket_ReceiveCallback(byte[] data, uint length, WebSocketClient.WEBSOCKET_PACKET_TYPES opcode,
WebSocketClient.WEBSOCKET_RESULT_CODES err)
{
if (opcode == WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__TEXT_FRAME)
{
var rx = System.Text.Encoding.UTF8.GetString(data, 0, (int)length);
if (rx.Length > 0)
ParseStreamRx(rx);
WSClient.ReceiveAsync();
}
else if (opcode == WebSocketClient.WEBSOCKET_PACKET_TYPES.LWS_WS_OPCODE_07__CLOSE)
{
Debug.Console(1, this, "Websocket disconnect received from remote");
CleanUpWebsocketClient();
}
else
{
Debug.Console(1, this, "websocket rx opcode/err {0}/{1}", opcode, err);
WSClient.ReceiveAsync();
}
return 0;
}
/// <summary>
/// Callback to catch possible errors in sending via the websocket
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
int Websocket_SendCallback(Crestron.SimplSharp.CrestronWebSocketClient.WebSocketClient.WEBSOCKET_RESULT_CODES result)
{
if(result != WebSocketClient.WEBSOCKET_RESULT_CODES.WEBSOCKET_CLIENT_SUCCESS)
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "SendCallback questionable result: {0}", result);
return 1;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ParseStreamRx(string message)
{
if(string.IsNullOrEmpty(message))
return;
if (!message.Contains("/system/heartbeat"))
{
Debug.Console(1, this, "Message RX: {0}", message);
}
else
{
LastAckMessage = DateTime.Now;
}
try
{
var messageObj = JObject.Parse(message);
var type = messageObj["type"].Value<string>();
if (type == "hello")
{
SendInitialMessage();
ResetOrStartHearbeatTimer();
}
else if (type == "/system/heartbeat")
{
HandleHeartBeat(messageObj["content"]);
}
else if (type == "raw")
{
var wrapper = messageObj["content"].ToObject<DeviceActionWrapper>();
DeviceJsonApi.DoDeviceAction(wrapper);
}
else if (type == "close")
{
Debug.Console(1, this, "Received close message from server.");
// DisconnectWebsocketClient();
if (ServerHeartbeatCheckTimer != null)
ServerHeartbeatCheckTimer.Stop();
}
else
{
// Check path against Action dictionary
if (ActionDictionary.ContainsKey(type))
{
var action = ActionDictionary[type];
if (action is Action)
{
(action as Action)();
}
else if (action is PressAndHoldAction)
{
var stateString = messageObj["content"]["state"].Value<string>();
// Look for a button press event
if (!string.IsNullOrEmpty(stateString))
{
switch (stateString)
{
case "true":
{
if (!PushedActions.ContainsKey(type))
{
PushedActions.Add(type, new CTimer(o =>
{
(action as PressAndHoldAction)(false);
PushedActions.Remove(type);
}, null, ButtonHeartbeatInterval, ButtonHeartbeatInterval));
}
// Maybe add an else to reset the timer
break;
}
case "held":
{
if (PushedActions.ContainsKey(type))
{
PushedActions[type].Reset(ButtonHeartbeatInterval, ButtonHeartbeatInterval);
}
return;
}
case "false":
{
if (PushedActions.ContainsKey(type))
{
PushedActions[type].Stop();
PushedActions.Remove(type);
}
break;
}
}
(action as PressAndHoldAction)(stateString == "true");
}
}
else if (action is Action<bool>)
{
var stateString = messageObj["content"]["state"].Value<string>();
if (!string.IsNullOrEmpty(stateString))
{
(action as Action<bool>)(stateString == "true");
}
}
else if (action is Action<ushort>)
{
(action as Action<ushort>)(messageObj["content"]["value"].Value<ushort>());
}
else if (action is Action<string>)
{
(action as Action<string>)(messageObj["content"]["value"].Value<string>());
}
else if (action is Action<SourceSelectMessageContent>)
{
(action as Action<SourceSelectMessageContent>)(messageObj["content"]
.ToObject<SourceSelectMessageContent>());
}
}
else
{
Debug.Console(1, this, "-- Warning: Incoming message has no registered handler");
}
}
}
catch (Exception err)
{
//Debug.Console(1, "SseMessageLengthBeforeFailureCount: {0}", SseMessageLengthBeforeFailureCount);
//SseMessageLengthBeforeFailureCount = 0;
Debug.Console(1, this, "Unable to parse message: {0}", err);
}
}
void TestHttpRequest(string s)
{
{
s = s.Trim();
if (string.IsNullOrEmpty(s))
{
PrintTestHttpRequestUsage();
return;
}
var tokens = s.Split(' ');
if (tokens.Length < 2)
{
CrestronConsole.ConsoleCommandResponse("Too few paramaters\r");
PrintTestHttpRequestUsage();
return;
}
try
{
var url = tokens[1];
if (tokens[0].ToLower() == "get")
{
var resp = new HttpClient().Get(url);
CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
}
else if (tokens[0].ToLower() == "post")
{
var resp = new HttpClient().Post(url, new byte[] { });
CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
}
else
{
CrestronConsole.ConsoleCommandResponse("Only get or post supported\r");
PrintTestHttpRequestUsage();
}
}
catch (HttpException e)
{
CrestronConsole.ConsoleCommandResponse("Exception in request:\r");
CrestronConsole.ConsoleCommandResponse("Response URL: {0}\r", e.Response.ResponseUrl);
CrestronConsole.ConsoleCommandResponse("Response Error Code: {0}\r", e.Response.Code);
CrestronConsole.ConsoleCommandResponse("Response body: {0}\r", e.Response.ContentString);
}
}
}
void PrintTestHttpRequestUsage()
{
CrestronConsole.ConsoleCommandResponse("Usage: mobilehttprequest:N get/post url\r");
}
}
public class MobileControlSystemControllerFactory : EssentialsDeviceFactory<MobileControlSystemController>
{
public MobileControlSystemControllerFactory()
{
TypeNames = new List<string>() { "appserver" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new MobileControlSystemController Device");
var props = JsonConvert.DeserializeObject<MobileControlConfig>(dc.Properties.ToString());
return new MobileControlSystemController(dc.Key, dc.Name, props);
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public abstract class MobileControlBridgeBase: EssentialsDevice
{
public MobileControlSystemController Parent { get; private set; }
public string UserCode { get; private set; }
public abstract string RoomName { get; }
public MobileControlBridgeBase(string key, string name)
: base(key, name)
{
}
/// <summary>
/// Set the parent. Does nothing else. Override to add functionality such
/// as adding actions to parent
/// </summary>
/// <param name="parent"></param>
public virtual void AddParent(MobileControlSystemController parent)
{
Parent = parent;
}
/// <summary>
/// Sets the UserCode on the bridge object. Called from controller. A changed code will
/// fire method UserCodeChange. Override that to handle changes
/// </summary>
/// <param name="code"></param>
public void SetUserCode(string code)
{
var changed = UserCode != code;
UserCode = code;
if (changed)
{
UserCodeChange();
}
}
/// <summary>
/// Empty method in base class. Override this to add functionality
/// when code changes
/// </summary>
protected virtual void UserCodeChange()
{
}
}
}

View File

@@ -0,0 +1,484 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.MobileControl;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials
{
public class MobileConrolEssentialsHuddleSpaceRoomBridge : MobileControlBridgeBase
{
public EssentialsRoomBase Room { get; private set; }
public VideoCodecBaseMessenger VCMessenger { get; private set; }
public AudioCodecBaseMessenger ACMessenger { get; private set; }
public Dictionary<string, MessengerBase> DeviceMessengers { get; private set; }
/// <summary>
///
/// </summary>
public override string RoomName
{
get
{
return Room.Name;
}
}
/// <summary>
///
/// </summary>
/// <param name="parent"></param>
/// <param name="room"></param>
public MobileConrolEssentialsHuddleSpaceRoomBridge(EssentialsRoomBase room):
base("mobileControlBridge-essentialsHuddle", "Essentials Mobile Control Bridge-Huddle")
{
Room = room;
}
/// <summary>
/// Override of base: calls base to add parent and then registers actions and events.
/// </summary>
/// <param name="parent"></param>
public override void AddParent(MobileControlSystemController parent)
{
base.AddParent(parent);
// we add actions to the messaging system with a path, and a related action. Custom action
// content objects can be handled in the controller's LineReceived method - and perhaps other
// sub-controller parsing could be attached to these classes, so that the systemController
// doesn't need to know about everything.
// Source Changes and room off
Parent.AddAction(string.Format(@"/room/{0}/status", Room.Key), new Action(() => SendFullStatus(Room)));
var routeRoom = Room as IRunRouteAction;
if(routeRoom != null)
Parent.AddAction(string.Format(@"/room/{0}/source", Room.Key), new Action<SourceSelectMessageContent>(c =>
{
if(string.IsNullOrEmpty(c.SourceListKey))
routeRoom.RunRouteAction(c.SourceListItem, Room.SourceListKey);
else
{
routeRoom.RunRouteAction(c.SourceListItem, c.SourceListKey);
}
}));
var defaultRoom = Room as IRunDefaultPresentRoute;
if(defaultRoom != null)
Parent.AddAction(string.Format(@"/room/{0}/defaultsource", Room.Key), new Action(() => defaultRoom.RunDefaultPresentRoute()));
var volumeRoom = Room as IHasCurrentVolumeControls;
if (volumeRoom != null)
{
Parent.AddAction(string.Format(@"/room/{0}/volumes/master/level", Room.Key), new Action<ushort>(u =>
(volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(u)));
Parent.AddAction(string.Format(@"/room/{0}/volumes/master/muteToggle", Room.Key), new Action(() =>
volumeRoom.CurrentVolumeControls.MuteToggle()));
volumeRoom.CurrentVolumeDeviceChange += new EventHandler<VolumeDeviceChangeEventArgs>(Room_CurrentVolumeDeviceChange);
// Registers for initial volume events, if possible
var currentVolumeDevice = volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
if (currentVolumeDevice != null)
{
currentVolumeDevice.MuteFeedback.OutputChange += MuteFeedback_OutputChange;
currentVolumeDevice.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
}
}
var sscRoom = Room as IHasCurrentSourceInfoChange;
if(sscRoom != null)
sscRoom.CurrentSourceChange += new SourceInfoChangeHandler(Room_CurrentSingleSourceChange);
var vcRoom = Room as IHasVideoCodec;
if (vcRoom != null && vcRoom.VideoCodec != null)
{
var codec = vcRoom.VideoCodec;
var key = vcRoom.VideoCodec.Key + "-" + parent.Key;
VCMessenger = new VideoCodecBaseMessenger(key, vcRoom.VideoCodec, "/device/videoCodec");
VCMessenger.RegisterWithAppServer(Parent);
vcRoom.IsSharingFeedback.OutputChange += new EventHandler<FeedbackEventArgs>(IsSharingFeedback_OutputChange);
}
var acRoom = Room as IHasAudioCodec;
if (acRoom != null && acRoom.AudioCodec != null)
{
var codec = acRoom.AudioCodec;
var key = acRoom.AudioCodec.Key + "-" + parent.Key;
ACMessenger = new AudioCodecBaseMessenger(key, acRoom.AudioCodec, "/device/audioCodec");
ACMessenger.RegisterWithAppServer(Parent);
}
SetupDeviceMessengers();
var defCallRm = Room as IRunDefaultCallRoute;
if (defCallRm != null)
{
Parent.AddAction(string.Format(@"/room/{0}/activityVideo", Room.Key), new Action(()=>defCallRm.RunDefaultCallRoute()));
}
Parent.AddAction(string.Format(@"/room/{0}/shutdownStart", Room.Key), new Action(() => Room.StartShutdown(eShutdownType.Manual)));
Parent.AddAction(string.Format(@"/room/{0}/shutdownEnd", Room.Key), new Action(() => Room.ShutdownPromptTimer.Finish()));
Parent.AddAction(string.Format(@"/room/{0}/shutdownCancel", Room.Key), new Action(() => Room.ShutdownPromptTimer.Cancel()));
Room.OnFeedback.OutputChange += OnFeedback_OutputChange;
Room.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
Room.IsWarmingUpFeedback.OutputChange += IsWarmingUpFeedback_OutputChange;
Room.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
Room.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
Room.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
}
/// <summary>
/// Set up the messengers for each device type
/// </summary>
void SetupDeviceMessengers()
{
DeviceMessengers = new Dictionary<string,MessengerBase>();
foreach (var device in DeviceManager.AllDevices)
{
Debug.Console(2, this, "Attempting to set up device messenger for device: {0}", device.Key);
if (device is Essentials.Devices.Common.Cameras.CameraBase)
{
var camDevice = device as Essentials.Devices.Common.Cameras.CameraBase;
Debug.Console(2, this, "Adding CameraBaseMessenger for device: {0}", device.Key);
var cameraMessenger = new CameraBaseMessenger(device.Key + "-" + Parent.Key, camDevice, "/device/" + device.Key);
DeviceMessengers.Add(device.Key, cameraMessenger);
cameraMessenger.RegisterWithAppServer(Parent);
}
if (device is Essentials.Devices.Common.SoftCodec.BlueJeansPc)
{
var softCodecDevice = device as Essentials.Devices.Common.SoftCodec.BlueJeansPc;
Debug.Console(2, this, "Adding IRunRouteActionMessnger for device: {0}", device.Key);
var routeMessenger = new IRunRouteActionMessenger(device.Key + "-" + Parent.Key, softCodecDevice, "/device/" + device.Key);
DeviceMessengers.Add(device.Key, routeMessenger);
routeMessenger.RegisterWithAppServer(Parent);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IsSharingFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
// sharing source
string shareText;
bool isSharing;
#warning This share update needs to happen on source change as well!
var vcRoom = Room as IHasVideoCodec;
var srcInfoRoom = Room as IHasCurrentSourceInfoChange;
if (vcRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && srcInfoRoom.CurrentSourceInfo != null)
{
shareText = srcInfoRoom.CurrentSourceInfo.PreferredName;
isSharing = true;
}
else
{
shareText = "None";
isSharing = false;
}
PostStatusMessage(new
{
share = new
{
currentShareText = shareText,
isSharing = isSharing
}
});
}
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="contentObject">The contents of the content object</param>
void PostStatusMessage(object contentObject)
{
Parent.SendMessageToServer(JObject.FromObject(new
{
type = "/room/status/",
content = contentObject
}));
}
/// <summary>
/// Handler for cancelled shutdown
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
{
JObject roomStatus = new JObject();
roomStatus.Add("state", "wasCancelled");
JObject message = new JObject();
message.Add("type", "/room/shutdown/");
message.Add("content", roomStatus);
Parent.SendMessageToServer(message);
}
/// <summary>
/// Handler for when shutdown finishes
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
{
JObject roomStatus = new JObject();
roomStatus.Add("state", "hasFinished");
JObject message = new JObject();
message.Add("type", "/room/shutdown/");
message.Add("content", roomStatus);
Parent.SendMessageToServer(message);
}
/// <summary>
/// Handler for when shutdown starts
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_HasStarted(object sender, EventArgs e)
{
JObject roomStatus = new JObject();
roomStatus.Add("state", "hasStarted");
roomStatus.Add("duration", Room.ShutdownPromptTimer.SecondsToCount);
JObject message = new JObject();
message.Add("type", "/room/shutdown/");
message.Add("content", roomStatus);
Parent.SendMessageToServer(message);
// equivalent JS message:
// Post( { type: '/room/status/', content: { shutdown: 'hasStarted', duration: Room.ShutdownPromptTimer.SecondsToCount })
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IsWarmingUpFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostStatusMessage(new
{
isWarmingUp = e.BoolValue
});
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void IsCoolingDownFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostStatusMessage(new
{
isCoolingDown = e.BoolValue
});
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void OnFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostStatusMessage(new
{
isOn = e.BoolValue
});
}
void Room_CurrentVolumeDeviceChange(object sender, VolumeDeviceChangeEventArgs e)
{
if (e.OldDev is IBasicVolumeWithFeedback)
{
var oldDev = e.OldDev as IBasicVolumeWithFeedback;
oldDev.MuteFeedback.OutputChange -= MuteFeedback_OutputChange;
oldDev.VolumeLevelFeedback.OutputChange -= VolumeLevelFeedback_OutputChange;
}
if (e.NewDev is IBasicVolumeWithFeedback)
{
var newDev = e.NewDev as IBasicVolumeWithFeedback;
newDev.MuteFeedback.OutputChange += MuteFeedback_OutputChange;
newDev.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
}
}
/// <summary>
/// Event handler for mute changes
/// </summary>
void MuteFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostStatusMessage(new
{
volumes = new
{
master = new
{
muted = e.BoolValue
}
}
});
}
/// <summary>
/// Handles Volume changes on room
/// </summary>
void VolumeLevelFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostStatusMessage(new
{
volumes = new
{
master = new
{
level = e.IntValue
}
}
});
}
void Room_CurrentSingleSourceChange(PepperDash.Essentials.Core.SourceListItem info, ChangeType type)
{
/* Example message
* {
"type":"/room/status",
"content": {
"selectedSourceKey": "off",
}
}
*/
if (type == ChangeType.WillChange)
{
// Disconnect from previous source
if (info != null)
{
var previousDev = info.SourceDevice;
// device type interfaces
if (previousDev is ISetTopBoxControls)
(previousDev as ISetTopBoxControls).UnlinkActions(Parent);
// common interfaces
if (previousDev is IChannel)
(previousDev as IChannel).UnlinkActions(Parent);
if (previousDev is IColor)
(previousDev as IColor).UnlinkActions(Parent);
if (previousDev is IDPad)
(previousDev as IDPad).UnlinkActions(Parent);
if (previousDev is IDvr)
(previousDev as IDvr).UnlinkActions(Parent);
if (previousDev is INumericKeypad)
(previousDev as INumericKeypad).UnlinkActions(Parent);
if (previousDev is IPower)
(previousDev as IPower).UnlinkActions(Parent);
if (previousDev is ITransport)
(previousDev as ITransport).UnlinkActions(Parent);
}
}
else // did change
{
if (info != null)
{
var dev = info.SourceDevice;
if (dev is ISetTopBoxControls)
(dev as ISetTopBoxControls).LinkActions(Parent);
if (dev is IChannel)
(dev as IChannel).LinkActions(Parent);
if (dev is IColor)
(dev as IColor).LinkActions(Parent);
if (dev is IDPad)
(dev as IDPad).LinkActions(Parent);
if (dev is IDvr)
(dev as IDvr).LinkActions(Parent);
if (dev is INumericKeypad)
(dev as INumericKeypad).LinkActions(Parent);
if (dev is IPower)
(dev as IPower).LinkActions(Parent);
if (dev is ITransport)
(dev as ITransport).LinkActions(Parent);
var srcRm = Room as IHasCurrentSourceInfoChange;
if (srcRm != null)
{
PostStatusMessage(new
{
selectedSourceKey = srcRm.CurrentSourceInfoKey
});
}
}
}
}
/// <summary>
/// Posts the full status of the room to the server
/// </summary>
/// <param name="room"></param>
void SendFullStatus(EssentialsRoomBase room)
{
var sourceKey = room is IHasCurrentSourceInfoChange ? (room as IHasCurrentSourceInfoChange).CurrentSourceInfoKey : null;
var rmVc = room as IHasCurrentVolumeControls;
var volumes = new Volumes();
if (rmVc != null)
{
var vc = rmVc.CurrentVolumeControls as IBasicVolumeWithFeedback;
if (vc != null)
{
volumes.Master = new Volume("master", vc.VolumeLevelFeedback.UShortValue, vc.MuteFeedback.BoolValue, "Volume", true, "");
}
}
PostStatusMessage(new
{
//calls = GetCallsMessageObject(),
isOn = room.OnFeedback.BoolValue,
selectedSourceKey = sourceKey,
//vtc = GetVtcCallsMessageObject(),
volumes = volumes
});
}
}
/// <summary>
///
/// </summary>
public class SourceSelectMessageContent
{
public string SourceListItem { get; set; }
public string SourceListKey { get; set; }
}
/// <summary>
///
/// </summary>
/// <param name="b"></param>
public delegate void PressAndHoldAction(bool b);
}

View File

@@ -0,0 +1,859 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro.EthernetCommunication;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.AppServer;
using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials.Room.MobileControl
{
public class MobileControlSIMPLRoomBridge : MobileControlBridgeBase, IDelayedConfiguration
{
/// <summary>
/// Fires when config is ready to go
/// </summary>
public event EventHandler<EventArgs> ConfigurationIsReady;
public ThreeSeriesTcpIpEthernetIntersystemCommunications EISC { get; private set; }
public MobileControlSIMPLRoomJoinMap JoinMap { get; private set; }
/// <summary>
///
/// </summary>
public bool ConfigIsLoaded { get; private set; }
public override string RoomName
{
get {
var name = EISC.StringOutput[JoinMap.ConfigRoomName.JoinNumber].StringValue;
return string.IsNullOrEmpty(name) ? "Not Loaded" : name;
}
}
MobileControlDdvc01DeviceBridge SourceBridge;
SIMPLAtcMessenger AtcMessenger;
SIMPLVtcMessenger VtcMessenger;
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ipId"></param>
public MobileControlSIMPLRoomBridge(string key, string name, uint ipId)
: base(key, name)
{
try
{
EISC = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipId, "127.0.0.2", Global.ControlSystem);
var reg = EISC.Register();
if (reg != Crestron.SimplSharpPro.eDeviceRegistrationUnRegistrationResponse.Success)
Debug.Console(0, this, "Cannot connect EISC at IPID {0}: \r{1}", ipId, reg);
JoinMap = new MobileControlSIMPLRoomJoinMap(1);
SourceBridge = new MobileControlDdvc01DeviceBridge(key + "-sourceBridge", "DDVC01 source bridge", EISC);
DeviceManager.AddDevice(SourceBridge);
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Finish wiring up everything after all devices are created. The base class will hunt down the related
/// parent controller and link them up.
/// </summary>
/// <returns></returns>
public override bool CustomActivate()
{
Debug.Console(0, this, "Final activation. Setting up actions and feedbacks");
SetupFunctions();
SetupFeedbacks();
var atcKey = string.Format("atc-{0}-{1}", this.Key, Parent.Key);
AtcMessenger = new SIMPLAtcMessenger(atcKey, EISC, "/device/audioCodec");
AtcMessenger.RegisterWithAppServer(Parent);
var vtcKey = string.Format("atc-{0}-{1}", this.Key, Parent.Key);
VtcMessenger = new SIMPLVtcMessenger(vtcKey, EISC, "/device/videoCodec");
VtcMessenger.RegisterWithAppServer(Parent);
EISC.SigChange += EISC_SigChange;
EISC.OnlineStatusChange += (o, a) =>
{
Debug.Console(1, this, "DDVC EISC online={0}. Config is ready={1}. Use Essentials Config={2}",
a.DeviceOnLine, EISC.BooleanOutput[JoinMap.ConfigIsReady.JoinNumber].BoolValue, EISC.BooleanOutput[JoinMap.ConfigIsLocal.JoinNumber].BoolValue);
if (a.DeviceOnLine && EISC.BooleanOutput[JoinMap.ConfigIsReady.JoinNumber].BoolValue)
LoadConfigValues();
if (a.DeviceOnLine && EISC.BooleanOutput[JoinMap.ConfigIsLocal.JoinNumber].BoolValue)
UseEssentialsConfig();
};
// load config if it's already there
if (EISC.IsOnline && EISC.BooleanOutput[JoinMap.ConfigIsReady.JoinNumber].BoolValue) // || EISC.BooleanInput[JoinMap.ConfigIsReady].BoolValue)
LoadConfigValues();
if (EISC.IsOnline && EISC.BooleanOutput[JoinMap.ConfigIsLocal.JoinNumber].BoolValue)
{
UseEssentialsConfig();
}
CrestronConsole.AddNewConsoleCommand(s =>
{
for (uint i = 1; i < 1000; i++)
{
if (s.ToLower().Equals("b"))
{
CrestronConsole.ConsoleCommandResponse("D{0,6} {1} - ", i, EISC.BooleanOutput[i].BoolValue);
}
else if (s.ToLower().Equals("u"))
{
CrestronConsole.ConsoleCommandResponse("U{0,6} {1,8} - ", i, EISC.UShortOutput[i].UShortValue);
}
else if (s.ToLower().Equals("s"))
{
var val = EISC.StringOutput[i].StringValue;
if(!string.IsNullOrEmpty(val))
CrestronConsole.ConsoleCommandResponse("S{0,6} {1}\r", i, EISC.StringOutput[i].StringValue);
}
}
}, "mobilebridgedump", "Dumps DDVC01 bridge EISC data b,u,s", ConsoleAccessLevelEnum.AccessOperator);
return base.CustomActivate();
}
void UseEssentialsConfig()
{
ConfigIsLoaded = false;
SetupDeviceMessengers();
Debug.Console(0, this, "******* ESSENTIALS CONFIG: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
var handler = ConfigurationIsReady;
if (handler != null)
{
handler(this, new EventArgs());
}
ConfigIsLoaded = true;
}
/// <summary>
/// Setup the actions to take place on various incoming API calls
/// </summary>
void SetupFunctions()
{
Parent.AddAction(@"/room/room1/promptForCode", new Action(() => EISC.PulseBool(JoinMap.PromptForCode.JoinNumber)));
Parent.AddAction(@"/room/room1/clientJoined", new Action(() => EISC.PulseBool(JoinMap.ClientJoined.JoinNumber)));
Parent.AddAction(@"/room/room1/status", new Action(SendFullStatus));
Parent.AddAction(@"/room/room1/source", new Action<SourceSelectMessageContent>(c =>
{
EISC.SetString(JoinMap.CurrentSourceKey.JoinNumber, c.SourceListItem);
EISC.PulseBool(JoinMap.SourceHasChanged.JoinNumber);
}));
Parent.AddAction(@"/room/room1/defaultsource", new Action(() =>
EISC.PulseBool(JoinMap.ActivityShare.JoinNumber)));
Parent.AddAction(@"/room/room1/activityPhone", new Action(() =>
EISC.PulseBool(JoinMap.ActivityPhoneCall.JoinNumber)));
Parent.AddAction(@"/room/room1/activityVideo", new Action(() =>
EISC.PulseBool(JoinMap.ActivityVideoCall.JoinNumber)));
Parent.AddAction(@"/room/room1/volumes/master/level", new Action<ushort>(u =>
EISC.SetUshort(JoinMap.MasterVolume.JoinNumber, u)));
Parent.AddAction(@"/room/room1/volumes/master/muteToggle", new Action(() =>
EISC.PulseBool(JoinMap.MasterVolume.JoinNumber)));
Parent.AddAction(@"/room/room1/volumes/master/privacyMuteToggle", new Action(() =>
EISC.PulseBool(JoinMap.PrivacyMute.JoinNumber)));
// /xyzxyz/volumes/master/muteToggle ---> BoolInput[1]
var volumeStart = JoinMap.VolumeJoinStart.JoinNumber;
var volumeEnd = JoinMap.VolumeJoinStart.JoinNumber + JoinMap.VolumeJoinStart.JoinSpan;
for (uint i = volumeStart; i <= volumeEnd; i++)
{
var index = i;
Parent.AddAction(string.Format(@"/room/room1/volumes/level-{0}/level", index), new Action<ushort>(u =>
EISC.SetUshort(index, u)));
Parent.AddAction(string.Format(@"/room/room1/volumes/level-{0}/muteToggle", index), new Action(() =>
EISC.PulseBool(index)));
}
Parent.AddAction(@"/room/room1/shutdownStart", new Action(() =>
EISC.PulseBool(JoinMap.ShutdownStart.JoinNumber)));
Parent.AddAction(@"/room/room1/shutdownEnd", new Action(() =>
EISC.PulseBool(JoinMap.ShutdownEnd.JoinNumber)));
Parent.AddAction(@"/room/room1/shutdownCancel", new Action(() =>
EISC.PulseBool(JoinMap.ShutdownCancel.JoinNumber)));
}
/// <summary>
///
/// </summary>
/// <param name="devKey"></param>
void SetupSourceFunctions(string devKey)
{
SourceDeviceMapDictionary sourceJoinMap = new SourceDeviceMapDictionary();
var prefix = string.Format("/device/{0}/", devKey);
foreach (var item in sourceJoinMap)
{
var join = item.Value;
Parent.AddAction(string.Format("{0}{1}", prefix, item.Key), new PressAndHoldAction(b => EISC.SetBool(join, b)));
}
}
/// <summary>
/// Links feedbacks to whatever is gonna happen!
/// </summary>
void SetupFeedbacks()
{
// Power
EISC.SetBoolSigAction(JoinMap.RoomIsOn.JoinNumber, b =>
PostStatusMessage(new
{
isOn = b
}));
// Source change things
EISC.SetSigTrueAction(JoinMap.SourceHasChanged.JoinNumber, () =>
PostStatusMessage(new
{
selectedSourceKey = EISC.StringOutput[JoinMap.CurrentSourceKey.JoinNumber].StringValue
}));
// Volume things
EISC.SetUShortSigAction(JoinMap.MasterVolume.JoinNumber, u =>
PostStatusMessage(new
{
volumes = new
{
master = new
{
level = u
}
}
}));
// map MasterVolumeIsMuted join -> status/volumes/master/muted
//
EISC.SetBoolSigAction(JoinMap.MasterVolume.JoinNumber, b =>
PostStatusMessage(new
{
volumes = new
{
master = new
{
muted = b
}
}
}));
EISC.SetBoolSigAction(JoinMap.PrivacyMute.JoinNumber, b =>
PostStatusMessage(new
{
volumes = new
{
master = new
{
privacyMuted = b
}
}
}));
var volumeStart = JoinMap.VolumeJoinStart.JoinNumber;
var volumeEnd = JoinMap.VolumeJoinStart.JoinNumber + JoinMap.VolumeJoinStart.JoinSpan;
for (uint i = volumeStart; i <= volumeEnd; i++)
{
var index = i; // local scope for lambdas
EISC.SetUShortSigAction(index, u => // start at join 2
{
// need a dict in order to create the level-n property on auxFaders
var dict = new Dictionary<string, object>();
dict.Add("level-" + index, new { level = u });
PostStatusMessage(new
{
volumes = new
{
auxFaders = dict,
}
});
});
EISC.SetBoolSigAction(index, b =>
{
// need a dict in order to create the level-n property on auxFaders
var dict = new Dictionary<string, object>();
dict.Add("level-" + index, new { muted = b });
PostStatusMessage(new
{
volumes = new
{
auxFaders = dict,
}
});
});
}
EISC.SetUShortSigAction(JoinMap.NumberOfAuxFaders.JoinNumber, u =>
PostStatusMessage(new {
volumes = new {
numberOfAuxFaders = u,
}
}));
// shutdown things
EISC.SetSigTrueAction(JoinMap.ShutdownCancel.JoinNumber, new Action(() =>
PostMessage("/room/shutdown/", new
{
state = "wasCancelled"
})));
EISC.SetSigTrueAction(JoinMap.ShutdownEnd.JoinNumber, new Action(() =>
PostMessage("/room/shutdown/", new
{
state = "hasFinished"
})));
EISC.SetSigTrueAction(JoinMap.ShutdownStart.JoinNumber, new Action(() =>
PostMessage("/room/shutdown/", new
{
state = "hasStarted",
duration = EISC.UShortOutput[JoinMap.ShutdownPromptDuration.JoinNumber].UShortValue
})));
// Config things
EISC.SetSigTrueAction(JoinMap.ConfigIsReady.JoinNumber, LoadConfigValues);
// Activity modes
EISC.SetSigTrueAction(JoinMap.ActivityShare.JoinNumber, () => UpdateActivity(1));
EISC.SetSigTrueAction(JoinMap.ActivityPhoneCall.JoinNumber, () => UpdateActivity(2));
EISC.SetSigTrueAction(JoinMap.ActivityVideoCall.JoinNumber, () => UpdateActivity(3));
}
/// <summary>
/// Updates activity states
/// </summary>
void UpdateActivity(int mode)
{
PostStatusMessage(new
{
activityMode = mode,
});
}
/// <summary>
/// Reads in config values when the Simpl program is ready
/// </summary>
void LoadConfigValues()
{
Debug.Console(1, this, "Loading configuration from DDVC01 EISC bridge");
ConfigIsLoaded = false;
var co = ConfigReader.ConfigObject;
co.Info.RuntimeInfo.AppName = Assembly.GetExecutingAssembly().GetName().Name;
var version = Assembly.GetExecutingAssembly().GetName().Version;
co.Info.RuntimeInfo.AssemblyVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
//Room
//if (co.Rooms == null)
// always start fresh in case simpl changed
co.Rooms = new List<DeviceConfig>();
var rm = new DeviceConfig();
if (co.Rooms.Count == 0)
{
Debug.Console(0, this, "Adding room to config");
co.Rooms.Add(rm);
}
else
{
Debug.Console(0, this, "Replacing Room[0] in config");
co.Rooms[0] = rm;
}
rm.Name = EISC.StringOutput[JoinMap.ConfigRoomName.JoinNumber].StringValue;
rm.Key = "room1";
rm.Type = "ddvc01";
DDVC01RoomPropertiesConfig rmProps;
if (rm.Properties == null)
rmProps = new DDVC01RoomPropertiesConfig();
else
rmProps = JsonConvert.DeserializeObject<DDVC01RoomPropertiesConfig>(rm.Properties.ToString());
rmProps.Help = new EssentialsHelpPropertiesConfig();
rmProps.Help.CallButtonText = EISC.StringOutput[JoinMap.ConfigHelpNumber.JoinNumber].StringValue;
rmProps.Help.Message = EISC.StringOutput[JoinMap.ConfigHelpMessage.JoinNumber].StringValue;
rmProps.Environment = new EssentialsEnvironmentPropertiesConfig(); // enabled defaults to false
rmProps.RoomPhoneNumber = EISC.StringOutput[JoinMap.ConfigRoomPhoneNumber.JoinNumber].StringValue;
rmProps.RoomURI = EISC.StringOutput[JoinMap.ConfigRoomURI.JoinNumber].StringValue;
rmProps.SpeedDials = new List<DDVC01SpeedDial>();
// This MAY need a check
rmProps.AudioCodecKey = "audioCodec";
rmProps.VideoCodecKey = "videoCodec";
// volume control names
var volCount = EISC.UShortOutput[JoinMap.NumberOfAuxFaders.JoinNumber].UShortValue;
//// use Volumes object or?
//rmProps.VolumeSliderNames = new List<string>();
//for(uint i = 701; i <= 700 + volCount; i++)
//{
// rmProps.VolumeSliderNames.Add(EISC.StringInput[i].StringValue);
//}
// There should be Mobile Control devices in here, I think...
if(co.Devices == null)
co.Devices = new List<DeviceConfig>();
// clear out previous DDVC devices
co.Devices.RemoveAll(d =>
d.Key.StartsWith("source-", StringComparison.OrdinalIgnoreCase)
|| d.Key.Equals("audioCodec", StringComparison.OrdinalIgnoreCase)
|| d.Key.Equals("videoCodec", StringComparison.OrdinalIgnoreCase));
rmProps.SourceListKey = "default";
rm.Properties = JToken.FromObject(rmProps);
// Source list! This might be brutal!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
var groupMap = GetSourceGroupDictionary();
co.SourceLists = new Dictionary<string,Dictionary<string,SourceListItem>>();
var newSl = new Dictionary<string, SourceListItem>();
// add "none" source if VTC present
if (!string.IsNullOrEmpty(rmProps.VideoCodecKey))
{
var codecOsd = new SourceListItem()
{
Name = "None",
IncludeInSourceList = true,
Order = 1,
Type = eSourceListItemType.Route,
SourceKey = ""
};
newSl.Add("Source-None", codecOsd);
}
// add sources...
for (uint i = 0; i <= 19; i++)
{
var name = EISC.StringOutput[JoinMap.SourceNameJoinStart.JoinNumber + i].StringValue;
if (EISC.BooleanOutput[JoinMap.UseSourceEnabled.JoinNumber].BoolValue
&& !EISC.BooleanOutput[JoinMap.SourceIsEnabledJoinStart.JoinNumber + i].BoolValue)
{
continue;
}
else if(!EISC.BooleanOutput[JoinMap.UseSourceEnabled.JoinNumber].BoolValue && string.IsNullOrEmpty(name))
break;
var icon = EISC.StringOutput[JoinMap.SourceIconJoinStart.JoinNumber + i].StringValue;
var key = EISC.StringOutput[JoinMap.SourceKeyJoinStart.JoinNumber + i].StringValue;
var type = EISC.StringOutput[JoinMap.SourceTypeJoinStart.JoinNumber + i].StringValue;
var disableShare = EISC.BooleanOutput[JoinMap.SourceShareDisableJoinStart.JoinNumber + i].BoolValue;
Debug.Console(0, this, "Adding source {0} '{1}'", key, name);
var newSLI = new SourceListItem{
Icon = icon,
Name = name,
Order = (int)i + 10,
SourceKey = key,
Type = eSourceListItemType.Route,
DisableCodecSharing = disableShare,
};
newSl.Add(key, newSLI);
string group = "genericsource";
if (groupMap.ContainsKey(type))
{
group = groupMap[type];
}
// add dev to devices list
var devConf = new DeviceConfig {
Group = group,
Key = key,
Name = name,
Type = type
};
co.Devices.Add(devConf);
if (group.ToLower().StartsWith("settopbox")) // Add others here as needed
{
SetupSourceFunctions(key);
}
}
co.SourceLists.Add("default", newSl);
// Build "audioCodec" config if we need
if (!string.IsNullOrEmpty(rmProps.AudioCodecKey))
{
var acFavs = new List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem>();
for (uint i = 0; i < 4; i++)
{
if (!EISC.GetBool(JoinMap.SpeedDialVisibleStartJoin.JoinNumber + i))
{
break;
}
acFavs.Add(new PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem()
{
Name = EISC.GetString(JoinMap.SpeedDialNameStartJoin.JoinNumber + i),
Number = EISC.GetString(JoinMap.SpeedDialNumberStartJoin.JoinNumber + i),
Type = PepperDash.Essentials.Devices.Common.Codec.eCodecCallType.Audio
});
}
var acProps = new
{
favorites = acFavs
};
var acStr = "audioCodec";
var acConf = new DeviceConfig()
{
Group = acStr,
Key = acStr,
Name = acStr,
Type = acStr,
Properties = JToken.FromObject(acProps)
};
co.Devices.Add(acConf);
}
// Build Video codec config
if (!string.IsNullOrEmpty(rmProps.VideoCodecKey))
{
// No favorites, for now?
var favs = new List<PepperDash.Essentials.Devices.Common.Codec.CodecActiveCallItem>();
// cameras
var camsProps = new List<object>();
for (uint i = 0; i < 9; i++)
{
var name = EISC.GetString(i + JoinMap.CameraNearNameStart.JoinNumber);
if (!string.IsNullOrEmpty(name))
{
camsProps.Add(new
{
name = name,
selector = "camera" + (i + 1),
});
}
}
var farName = EISC.GetString(JoinMap.CameraFarName.JoinNumber);
if (!string.IsNullOrEmpty(farName))
{
camsProps.Add(new
{
name = farName,
selector = "cameraFar",
});
}
var props = new
{
favorites = favs,
cameras = camsProps,
};
var str = "videoCodec";
var conf = new DeviceConfig()
{
Group = str,
Key = str,
Name = str,
Type = str,
Properties = JToken.FromObject(props)
};
co.Devices.Add(conf);
}
SetupDeviceMessengers();
Debug.Console(0, this, "******* CONFIG FROM DDVC: \r{0}", JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
var handler = ConfigurationIsReady;
if (handler != null)
{
handler(this, new EventArgs());
}
ConfigIsLoaded = true;
}
/// <summary>
/// Iterates device config and adds messengers as neede for each device type
/// </summary>
void SetupDeviceMessengers()
{
try
{
foreach (var device in ConfigReader.ConfigObject.Devices)
{
if (device.Group.Equals("simplmessenger"))
{
var props = JsonConvert.DeserializeObject<SimplMessengerPropertiesConfig>(device.Properties.ToString());
var messengerKey = string.Format("device-{0}-{1}", this.Key, Parent.Key);
if (DeviceManager.GetDeviceForKey(messengerKey) != null)
{
Debug.Console(2, this, "Messenger with key: {0} already exists. Skipping...", messengerKey);
continue;
}
var dev = ConfigReader.ConfigObject.GetDeviceForKey(props.DeviceKey);
if (dev == null)
{
Debug.Console(1, this, "Unable to find device config for key: '{0}'", props.DeviceKey);
continue;
}
var type = device.Type.ToLower();
MessengerBase messenger = null;
if (type.Equals("simplcameramessenger"))
{
Debug.Console(2, this, "Adding SIMPLCameraMessenger for: '{0}'", props.DeviceKey);
messenger = new SIMPLCameraMessenger(messengerKey, EISC, "/device/" + props.DeviceKey, props.JoinStart);
}
else if (type.Equals("simplroutemessenger"))
{
Debug.Console(2, this, "Adding SIMPLRouteMessenger for: '{0}'", props.DeviceKey);
messenger = new SIMPLRouteMessenger(messengerKey, EISC, "/device/" + props.DeviceKey, props.JoinStart);
}
if (messenger != null)
{
DeviceManager.AddDevice(messenger);
messenger.RegisterWithAppServer(Parent);
}
else
{
Debug.Console(2, this, "Unable to add messenger for device: '{0}' of type: '{1}'", props.DeviceKey, type);
}
}
}
}
catch (Exception e)
{
Debug.Console(2, this, "Error Setting up Device Managers: {0}", e);
}
}
/// <summary>
///
/// </summary>
void SendFullStatus()
{
if (ConfigIsLoaded)
{
var count = EISC.UShortOutput[JoinMap.NumberOfAuxFaders.JoinNumber].UShortValue;
Debug.Console(1, this, "The Fader Count is : {0}", count);
// build volumes object, serialize and put in content of method below
// Create auxFaders
var auxFaderDict = new Dictionary<string, Volume>();
var volumeStart = JoinMap.VolumeJoinStart.JoinNumber;
var volumeEnd = JoinMap.VolumeJoinStart.JoinNumber + JoinMap.VolumeJoinStart.JoinSpan;
for (uint i = volumeStart; i <= count; i++)
{
auxFaderDict.Add("level-" + i,
new Volume("level-" + i,
EISC.UShortOutput[i].UShortValue,
EISC.BooleanOutput[i].BoolValue,
EISC.StringOutput[i].StringValue,
true,
"someting.png"));
}
var volumes = new Volumes();
volumes.Master = new Volume("master",
EISC.UShortOutput[JoinMap.MasterVolume.JoinNumber].UShortValue,
EISC.BooleanOutput[JoinMap.MasterVolume.JoinNumber].BoolValue,
EISC.StringOutput[JoinMap.MasterVolume.JoinNumber].StringValue,
true,
"something.png");
volumes.Master.HasPrivacyMute = true;
volumes.Master.PrivacyMuted = EISC.BooleanOutput[JoinMap.PrivacyMute.JoinNumber].BoolValue;
volumes.AuxFaders = auxFaderDict;
volumes.NumberOfAuxFaders = EISC.UShortInput[JoinMap.NumberOfAuxFaders.JoinNumber].UShortValue;
PostStatusMessage(new
{
activityMode = GetActivityMode(),
isOn = EISC.BooleanOutput[JoinMap.RoomIsOn.JoinNumber].BoolValue,
selectedSourceKey = EISC.StringOutput[JoinMap.CurrentSourceKey.JoinNumber].StringValue,
volumes = volumes
});
}
else
{
PostStatusMessage(new
{
error = "systemNotReady"
});
}
}
/// <summary>
/// Returns the activity mode int
/// </summary>
/// <returns></returns>
int GetActivityMode()
{
if (EISC.BooleanOutput[JoinMap.ActivityPhoneCall.JoinNumber].BoolValue) return 2;
else if (EISC.BooleanOutput[JoinMap.ActivityShare.JoinNumber].BoolValue) return 1;
else if (EISC.BooleanOutput[JoinMap.ActivityVideoCall.JoinNumber].BoolValue) return 3;
return 0;
}
/// <summary>
/// Helper for posting status message
/// </summary>
/// <param name="contentObject">The contents of the content object</param>
void PostStatusMessage(object contentObject)
{
Parent.SendMessageToServer(JObject.FromObject(new
{
type = "/room/status/",
content = contentObject
}));
}
/// <summary>
///
/// </summary>
/// <param name="messageType"></param>
/// <param name="contentObject"></param>
void PostMessage(string messageType, object contentObject)
{
Parent.SendMessageToServer(JObject.FromObject(new
{
type = messageType,
content = contentObject
}));
}
/// <summary>
///
/// </summary>
/// <param name="currentDevice"></param>
/// <param name="args"></param>
void EISC_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level >= 1)
Debug.Console(1, this, "DDVC EISC change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo != null)
{
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);
}
}
/// <summary>
/// Returns the mapping of types to groups, for setting up devices.
/// </summary>
/// <returns></returns>
Dictionary<string, string> GetSourceGroupDictionary()
{
//type, group
var d = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "laptop", "pc" },
{ "pc", "pc" },
{ "wireless", "genericsource" },
{ "iptv", "settopbox" }
};
return d;
}
/// <summary>
/// updates the usercode from server
/// </summary>
protected override void UserCodeChange()
{
Debug.Console(1, this, "Server user code changed: {0}", UserCode);
EISC.StringInput[JoinMap.UserCodeToSystem.JoinNumber].StringValue = UserCode;
EISC.StringInput[JoinMap.ServerUrl.JoinNumber].StringValue = Parent.Config.ClientAppUrl;
}
}
public class MobileControlSIMPLRoomBridgeFactory : EssentialsDeviceFactory<MobileControlSIMPLRoomBridge>
{
public MobileControlSIMPLRoomBridgeFactory()
{
TypeNames = new List<string>() { "mobilecontrolbridge-ddvc01", "mobilecontrolbridge-simpl" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new MobileControlSIMPLRoomBridge Device");
var comm = CommFactory.GetControlPropertiesConfig(dc);
var bridge = new PepperDash.Essentials.Room.MobileControl.MobileControlSIMPLRoomBridge(dc.Key, dc.Name, comm.IpIdInt);
bridge.AddPreActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present");
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.AddBridge(bridge);
});
return bridge;
}
}
}

View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Room.MobileControl
{
/// <summary>
/// Contains all of the default joins that map to API funtions
/// </summary>
public class SourceDeviceMapDictionary : Dictionary<string, uint>
{
public SourceDeviceMapDictionary(): base()
{
var dictionary = new Dictionary<string, uint>
{
{"preset01", 101},
{"preset02", 102},
{"preset03", 103},
{"preset04", 104},
{"preset05", 105},
{"preset06", 106},
{"preset07", 107},
{"preset08", 108},
{"preset09", 109},
{"preset10", 110},
{"preset11", 111},
{"preset12", 112},
{"preset13", 113},
{"preset14", 114},
{"preset15", 115},
{"preset16", 116},
{"preset17", 117},
{"preset18", 118},
{"preset19", 119},
{"preset20", 120},
{"preset21", 121},
{"preset22", 122},
{"preset23", 123},
{"preset24", 124},
{"num0", 130},
{"num1", 131},
{"num2", 132},
{"num3", 133},
{"num4", 134},
{"num5", 135},
{"num6", 136},
{"num7", 137},
{"num8", 138},
{"num9", 139},
{"numDash", 140},
{"numEnter", 141},
{"chanUp", 142},
{"chanDown", 143},
{"lastChan", 144},
{"exit", 145},
{"powerToggle", 146},
{"red", 147},
{"green", 148},
{"yellow", 149},
{"blue", 150},
{"video", 151},
{"previous", 152},
{"next", 153},
{"rewind", 154},
{"ffwd", 155},
{"closedCaption", 156},
{"stop", 157},
{"pause", 158},
{"up", 159},
{"down", 160},
{"left", 161},
{"right", 162},
{"settings", 163},
{"info", 164},
{"return", 165},
{"guide", 166},
{"reboot", 167},
{"dvrList", 168},
{"replay", 169},
{"play", 170},
{"select", 171},
{"record", 172},
{"menu", 173},
{"topMenu", 174},
{"prevTrack", 175},
{"nextTrack", 176},
{"powerOn", 177},
{"powerOff", 178},
{"dot", 179}
};
foreach (var item in dictionary)
{
this.Add(item.Key, item.Value);
}
}
}
}

View File

@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer
{
public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
{
[JoinName("MasterVolume")]
public JoinDataComplete MasterVolume = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() {Label = "Master Volume Mute Toggle/FB/Level/Label", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalogSerial });
[JoinName("VolumeJoinStart")]
public JoinDataComplete VolumeJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 8 }, new JoinMetadata() {Label = "Volume Mute Toggle/FB/Level/Label", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalogSerial });
[JoinName("PrivacyMute")]
public JoinDataComplete PrivacyMute = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "Privacy Mute Toggle/FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("PromptForCode")]
public JoinDataComplete PromptForCode = new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 1 }, new JoinMetadata() {Label = "Prompt User for Code", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("ClientJoined")]
public JoinDataComplete ClientJoined = new JoinDataComplete(new JoinData() { JoinNumber = 42, JoinSpan = 1 }, new JoinMetadata() { Label = "Client Joined", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("ActivityShare")]
public JoinDataComplete ActivityShare = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() {Label = "Activity Share", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("ActivityPhoneCall")]
public JoinDataComplete ActivityPhoneCall = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Activity Phone Call", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("ActivityVideoCall")]
public JoinDataComplete ActivityVideoCall = new JoinDataComplete(new JoinData() { JoinNumber = 53, JoinSpan = 1 }, new JoinMetadata() { Label = "Activity Video Call", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("ShutdownPromptDuration")]
public JoinDataComplete ShutdownPromptDuration = new JoinDataComplete(new JoinData() { JoinNumber = 61, JoinSpan = 1 }, new JoinMetadata() { Label ="Shutdown Cancel", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("ShutdownCancel")]
public JoinDataComplete ShutdownCancel = new JoinDataComplete(new JoinData() { JoinNumber = 61, JoinSpan = 1 }, new JoinMetadata() { Label ="Shutdown Cancel", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("ShutdownEnd")]
public JoinDataComplete ShutdownEnd = new JoinDataComplete(new JoinData() { JoinNumber = 62, JoinSpan = 1 }, new JoinMetadata() { Label = "Shutdown End", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("ShutdownStart")]
public JoinDataComplete ShutdownStart = new JoinDataComplete(new JoinData() { JoinNumber = 63, JoinSpan = 1 }, new JoinMetadata() { Label = "Shutdown Start", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SourceHasChanged")]
public JoinDataComplete SourceHasChanged = new JoinDataComplete(new JoinData() { JoinNumber = 71, JoinSpan = 1 }, new JoinMetadata() { Label = "Source Changed", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CurrentSourceKey")]
public JoinDataComplete CurrentSourceKey = new JoinDataComplete(new JoinData() { JoinNumber = 71, JoinSpan = 1 }, new JoinMetadata() { Label = "Key of selected source", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigIsLocal")]
public JoinDataComplete ConfigIsLocal = new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 }, new JoinMetadata() { Label = "Config is local to Essentials", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("NumberOfAuxFaders")]
public JoinDataComplete NumberOfAuxFaders = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Number of Auxilliary Faders", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("SpeedDialNameStartJoin")]
public JoinDataComplete SpeedDialNameStartJoin = new JoinDataComplete(new JoinData() { JoinNumber = 241, JoinSpan = 10 }, new JoinMetadata() { Label = "Speed Dial names", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("SpeedDialNumberStartJoin")]
public JoinDataComplete SpeedDialNumberStartJoin = new JoinDataComplete(new JoinData() { JoinNumber = 251, JoinSpan = 10 }, new JoinMetadata() { Label = "Speed Dial numbers", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("SpeedDialVisibleStartJoin")]
public JoinDataComplete SpeedDialVisibleStartJoin = new JoinDataComplete(new JoinData() { JoinNumber = 261, JoinSpan = 10 }, new JoinMetadata() { Label = "Speed Dial Visible", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("RoomIsOn")]
public JoinDataComplete RoomIsOn = new JoinDataComplete(new JoinData() { JoinNumber = 301, JoinSpan = 1 }, new JoinMetadata() { Label = "Room Is On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("UserCodeToSystem")]
public JoinDataComplete UserCodeToSystem = new JoinDataComplete(new JoinData() { JoinNumber = 401, JoinSpan = 1 }, new JoinMetadata() { Label = "User Ccde", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("ServerUrl")]
public JoinDataComplete ServerUrl = new JoinDataComplete(new JoinData() { JoinNumber = 402, JoinSpan = 1 }, new JoinMetadata() { Label ="Server URL", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigRoomName")]
public JoinDataComplete ConfigRoomName = new JoinDataComplete(new JoinData() { JoinNumber = 501, JoinSpan = 1 }, new JoinMetadata() {Label = "Room Nnme", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigHelpMessage")]
public JoinDataComplete ConfigHelpMessage = new JoinDataComplete(new JoinData() { JoinNumber = 502, JoinSpan = 1 }, new JoinMetadata() { Label = "Room help message", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigHelpNumber")]
public JoinDataComplete ConfigHelpNumber = new JoinDataComplete(new JoinData() { JoinNumber = 503, JoinSpan = 1 }, new JoinMetadata() { Label = "Room help number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigRoomPhoneNumber")]
public JoinDataComplete ConfigRoomPhoneNumber = new JoinDataComplete(new JoinData() { JoinNumber = 504, JoinSpan = 1 }, new JoinMetadata() { Label = "Room phone number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigRoomURI")]
public JoinDataComplete ConfigRoomURI = new JoinDataComplete(new JoinData() { JoinNumber = 505, JoinSpan = 1 }, new JoinMetadata() { Label = "Room URI", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("ConfigIsReady")]
public JoinDataComplete ConfigIsReady = new JoinDataComplete(new JoinData() { JoinNumber = 501, JoinSpan = 1 }, new JoinMetadata() { Label = "Config info from SIMPL is ready", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("HideVideoConfRecents")]
public JoinDataComplete HideVideoConfRecents = new JoinDataComplete(new JoinData() { JoinNumber = 502, JoinSpan = 1 }, new JoinMetadata() { Label = "Hide Video Conference Recents", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("ShowCameraWhenNotInCall")]
public JoinDataComplete ShowCameraWhenNotInCall = new JoinDataComplete(new JoinData() { JoinNumber = 503, JoinSpan = 1 }, new JoinMetadata() { Label = "Show camera when not in call", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("UseSourceEnabled")]
public JoinDataComplete UseSourceEnabled = new JoinDataComplete(new JoinData() { JoinNumber = 504, JoinSpan = 1 }, new JoinMetadata() { Label = "Use Source Enabled Joins", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SourceShareDisableJoinStart")]
public JoinDataComplete SourceShareDisableJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 601, JoinSpan = 20 }, new JoinMetadata() { Label = "Source is not sharable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SourceIsEnabledJoinStart")]
public JoinDataComplete SourceIsEnabledJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 621, JoinSpan = 20 }, new JoinMetadata() { Label = "Source is enabled", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SourceNameJoinStart")]
public JoinDataComplete SourceNameJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 601, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Names", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("SourceIconJoinStart")]
public JoinDataComplete SourceIconJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 621, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Icons", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("SourceKeyJoinStart")]
public JoinDataComplete SourceKeyJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 641, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Keys", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("SourceTypeJoinStart")]
public JoinDataComplete SourceTypeJoinStart = new JoinDataComplete(new JoinData() { JoinNumber = 661, JoinSpan = 20 }, new JoinMetadata() { Label = "Source Types", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CameraNearNameStart")]
public JoinDataComplete CameraNearNameStart = new JoinDataComplete(new JoinData() { JoinNumber = 761, JoinSpan = 10 }, new JoinMetadata() { Label = "Near End Camera Names", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CameraFarName")]
public JoinDataComplete CameraFarName = new JoinDataComplete(new JoinData() { JoinNumber = 770, JoinSpan = 1 }, new JoinMetadata() { Label = "Far End Camera Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
public MobileControlSIMPLRoomJoinMap(uint joinStart)
:base(joinStart)
{
}
}
}

View File

@@ -0,0 +1,69 @@
using System.Linq;
using Crestron.SimplSharp.Reflection;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer
{
public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
{
[JoinName("EndCall")]
public JoinDataComplete EndCall = new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata() { Label = "Hang Up", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("IncomingAnswer")]
public JoinDataComplete IncomingAnswer = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Answer Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("IncomingReject")]
public JoinDataComplete IncomingReject = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Reject Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("SpeedDialStart")]
public JoinDataComplete SpeedDialStart = new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 }, new JoinMetadata() { Label = "Speed Dial", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CurrentDialString")]
public JoinDataComplete CurrentDialString = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Dial String", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CurrentCallNumber")]
public JoinDataComplete CurrentCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CurrentCallName")]
public JoinDataComplete CurrentCallName = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("HookState")]
public JoinDataComplete HookState = new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Hook State", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CallDirection")]
public JoinDataComplete CallDirection = new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Direction", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("IncomingCallName")]
public JoinDataComplete IncomingCallName = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("IncomingCallNumber")]
public JoinDataComplete IncomingCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("0")]
public JoinDataComplete Dtmf0 = new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 0", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("1")]
public JoinDataComplete Dtmf1 = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("2")]
public JoinDataComplete Dtmf2 = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("3")]
public JoinDataComplete Dtmf3 = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 3", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("4")]
public JoinDataComplete Dtmf4 = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 4", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("5")]
public JoinDataComplete Dtmf5 = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 5", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("6")]
public JoinDataComplete Dtmf6 = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 6", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("7")]
public JoinDataComplete Dtmf7 = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 7", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("8")]
public JoinDataComplete Dtmf8 = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 8", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("9")]
public JoinDataComplete Dtmf9 = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 9", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("*")]
public JoinDataComplete DtmfStar = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF *", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("#")]
public JoinDataComplete DtmfPound = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF #", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor that passes the joinStart to the base class
/// </summary>
/// <param name="joinStart"></param>
public SIMPLAtcJoinMap(uint joinStart)
: base(joinStart)
{
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer
{
public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
{
[JoinName("EndCall")]
public JoinDataComplete EndCall = new JoinDataComplete(new JoinData() { JoinNumber = 24, JoinSpan = 1 }, new JoinMetadata() { Label = "Hang Up", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("IncomingCall")]
public JoinDataComplete IncomingCall = new JoinDataComplete(new JoinData() { JoinNumber = 50, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("IncomingAnswer")]
public JoinDataComplete IncomingAnswer = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Answer Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("IncomingReject")]
public JoinDataComplete IncomingReject = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Reject Incoming Call", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("SpeedDialStart")]
public JoinDataComplete SpeedDialStart = new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 }, new JoinMetadata() { Label = "Speed Dial", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectorySearchBusy")]
public JoinDataComplete DirectorySearchBusy = new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Search Busy FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryLineSelected")]
public JoinDataComplete DirectoryLineSelected = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Line Selected FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryEntryIsContact")]
public JoinDataComplete DirectoryEntryIsContact = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Selected Entry Is Contact FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryIsRoot")]
public JoinDataComplete DirectoryIsRoot = new JoinDataComplete(new JoinData() { JoinNumber = 102, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory is on Root FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("DDirectoryHasChanged")]
public JoinDataComplete DDirectoryHasChanged = new JoinDataComplete(new JoinData() { JoinNumber = 103, JoinSpan = 1 }, new JoinMetadata() {Label = "Directory has changed FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryRoot")]
public JoinDataComplete DirectoryRoot = new JoinDataComplete(new JoinData() { JoinNumber = 104, JoinSpan = 1 }, new JoinMetadata() { Label = "Go to Directory Root", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryFolderBack")]
public JoinDataComplete DirectoryFolderBack = new JoinDataComplete(new JoinData() { JoinNumber = 105, JoinSpan = 1 }, new JoinMetadata() { Label = "Go back one directory level", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryDialSelectedLine")]
public JoinDataComplete DirectoryDialSelectedLine = new JoinDataComplete(new JoinData() { JoinNumber = 106, JoinSpan = 1 }, new JoinMetadata() { Label = "Dial selected directory line", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraTiltUp")]
public JoinDataComplete CameraTiltUp = new JoinDataComplete(new JoinData() { JoinNumber = 111, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Tilt Up", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraTiltDown")]
public JoinDataComplete CameraTiltDown = new JoinDataComplete(new JoinData() { JoinNumber = 112, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Tilt Down", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraPanLeft")]
public JoinDataComplete CameraPanLeft = new JoinDataComplete(new JoinData() { JoinNumber = 113, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Pan Left", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraPanRight")]
public JoinDataComplete CameraPanRight = new JoinDataComplete(new JoinData() { JoinNumber = 114, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Pan Right", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraZoomIn")]
public JoinDataComplete CameraZoomIn = new JoinDataComplete(new JoinData() { JoinNumber = 115, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Zoom In", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraZoomOut")]
public JoinDataComplete CameraZoomOut = new JoinDataComplete(new JoinData() { JoinNumber = 116, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Zoom Out", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraPresetStart")]
public JoinDataComplete CameraPresetStart = new JoinDataComplete(new JoinData() { JoinNumber = 121, JoinSpan = 5 }, new JoinMetadata() { Label = "Camera Presets", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraModeAuto")]
public JoinDataComplete CameraModeAuto = new JoinDataComplete(new JoinData() { JoinNumber = 131, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Auto", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraModeManual")]
public JoinDataComplete CameraModeManual = new JoinDataComplete(new JoinData() { JoinNumber = 132, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Manual", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraModeOff")]
public JoinDataComplete CameraModeOff = new JoinDataComplete(new JoinData() { JoinNumber = 133, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Mode Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraSelfView")]
public JoinDataComplete CameraSelfView = new JoinDataComplete(new JoinData() { JoinNumber = 141, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Self View Toggle/FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraLayout")]
public JoinDataComplete CameraLayout = new JoinDataComplete(new JoinData() { JoinNumber = 142, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Layout Toggle", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraSupportsAutoMode")]
public JoinDataComplete CameraSupportsAutoMode = new JoinDataComplete(new JoinData() { JoinNumber = 143, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Supports Auto Mode FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraSupportsOffMode")]
public JoinDataComplete CameraSupportsOffMode = new JoinDataComplete(new JoinData() { JoinNumber = 144, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Supports Off Mode FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CameraNumberSelect")]
public JoinDataComplete CameraNumberSelect = new JoinDataComplete(new JoinData() { JoinNumber = 60, JoinSpan = 1 }, new JoinMetadata() { Label = "Camera Number Select/FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectorySelectRow")]
public JoinDataComplete DirectorySelectRow = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Select Row", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("DirectoryRowCount")]
public JoinDataComplete DirectoryRowCount = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Row Count FB", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("CurrentDialString")]
public JoinDataComplete CurrentDialString = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Dial String", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CurrentCallName")]
public JoinDataComplete CurrentCallName = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CurrentCallNumber")]
public JoinDataComplete CurrentCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("HookState")]
public JoinDataComplete HookState = new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Hook State", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("CallDirection")]
public JoinDataComplete CallDirection = new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 }, new JoinMetadata() { Label = "Current Call Direction", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("IncomingCallName")]
public JoinDataComplete IncomingCallName = new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("IncomingCallNumber")]
public JoinDataComplete IncomingCallNumber = new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 }, new JoinMetadata() { Label = "Incoming Call Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("DirectorySearchString")]
public JoinDataComplete DirectorySearchString = new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 }, new JoinMetadata() { Label = "Directory Search String", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("DirectoryEntriesStart")]
public JoinDataComplete DirectoryEntriesStart = new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 255 }, new JoinMetadata() { Label = "Directory Entries", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("DirectoryEntrySelectedName")]
public JoinDataComplete DirectoryEntrySelectedName = new JoinDataComplete(new JoinData() { JoinNumber = 356, JoinSpan = 1 }, new JoinMetadata() { Label = "Selected Directory Entry Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("DirectoryEntrySelectedNumber")]
public JoinDataComplete DirectoryEntrySelectedNumber = new JoinDataComplete(new JoinData() { JoinNumber = 357, JoinSpan = 1 }, new JoinMetadata() { Label = "Selected Directory Entry Number", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("DirectorySelectedFolderName")]
public JoinDataComplete DirectorySelectedFolderName = new JoinDataComplete(new JoinData() { JoinNumber = 358, JoinSpan = 1 }, new JoinMetadata() { Label = "Selected Directory Folder Name", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Serial });
[JoinName("1")]
public JoinDataComplete Dtmf1 = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("2")]
public JoinDataComplete Dtmf2 = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("3")]
public JoinDataComplete Dtmf3 = new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 3", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("4")]
public JoinDataComplete Dtmf4 = new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 4", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("5")]
public JoinDataComplete Dtmf5 = new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 5", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("6")]
public JoinDataComplete Dtmf6 = new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 6", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("7")]
public JoinDataComplete Dtmf7 = new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 7", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("8")]
public JoinDataComplete Dtmf8 = new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 8", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("9")]
public JoinDataComplete Dtmf9 = new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 9", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("0")]
public JoinDataComplete Dtmf0 = new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF 0", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("*")]
public JoinDataComplete DtmfStar = new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF *", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("#")]
public JoinDataComplete DtmfPound = new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 }, new JoinMetadata() { Label = "DTMF #", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
public SIMPLVtcJoinMap(uint joinStart)
:base(joinStart)
{
}
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Room.MobileControl
{
public class Volumes
{
[JsonProperty("master")]
public Volume Master { get; set; }
[JsonProperty("auxFaders")]
public Dictionary<string, Volume> AuxFaders { get; set; }
[JsonProperty("numberOfAuxFaders")]
public int NumberOfAuxFaders { get; set; }
public Volumes()
{
AuxFaders = new Dictionary<string, Volume>();
}
}
public class Volume
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("level")]
public ushort Level { get; set; }
[JsonProperty("muted")]
public bool Muted { get; set; }
[JsonProperty("label")]
public string Label { get; set; }
[JsonProperty("hasMute")]
public bool HasMute { get; set; }
[JsonProperty("hasPrivacyMute")]
public bool HasPrivacyMute { get; set; }
[JsonProperty("privacyMuted")]
public bool PrivacyMuted { get; set; }
[JsonProperty("muteIcon")]
public string MuteIcon { get; set; }
public Volume(string key, ushort level, bool muted, string label, bool hasMute, string muteIcon)
{
Key = key;
Level = level;
Muted = muted;
Label = label;
HasMute = hasMute;
MuteIcon = muteIcon;
}
}
}

View File

@@ -1,7 +1,18 @@
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>
///
@@ -28,8 +39,6 @@ namespace PepperDash.Essentials.Room.Config
/// </summary>
public IBasicVolumeWithFeedback GetDevice()
{
throw new NotImplementedException("This method references DM CHASSIS Directly");
/*
// DM output card format: deviceKey--output~number, dm8x8-1--output~4
var match = Regex.Match(DeviceKey, @"([-_\w]+)--(\w+)~(\d+)");
if (match.Success)
@@ -46,7 +55,7 @@ namespace PepperDash.Essentials.Room.Config
return null;
}
// DSP/DMPS format: deviceKey--levelName, biampTesira-1--master
// DSP format: deviceKey--levelName, biampTesira-1--master
match = Regex.Match(DeviceKey, @"([-_\w]+)--(.+)");
if (match.Success)
{
@@ -58,34 +67,11 @@ namespace PepperDash.Essentials.Room.Config
if (dsp.LevelControlPoints.ContainsKey(levelTag)) // should always...
return dsp.LevelControlPoints[levelTag];
}
var dmps = DeviceManager.GetDeviceForKey(devKey) as DmpsAudioOutputController;
if (dmps != null)
{
var levelTag = match.Groups[2].Value;
switch (levelTag)
{
case "master":
return dmps.MasterVolumeLevel;
case "source":
return dmps.SourceVolumeLevel;
case "micsmaster":
return dmps.MicsMasterVolumeLevel;
case "codec1":
return dmps.Codec1VolumeLevel;
case "codec2":
return dmps.Codec2VolumeLevel;
default:
return dmps.MasterVolumeLevel;
}
}
// No volume for some reason. We have failed as developers
return null;
}
return null;
}
* */
}
}
}

View 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]);
}
}
}

View 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));
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View File

@@ -0,0 +1,38 @@
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.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;
}
}
}

View 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);
});
}
}
}
}
}

View 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;
}));
}
}
}
}

View 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]);
}
}
}

View 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;
}));
}
}
}
}

View File

@@ -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)));
}
}
}

View 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]);
}
}
}
}

View 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;
}
}
}

View File

@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Bridges;
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; }
protected Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
public EiscApi(DeviceConfig dc) :
base(dc.Key)
{
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
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;
Eisc.Register();
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 (device is IBridge) // 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;
dev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
}
if (!(device is IBridgeAdvanced)) continue;
Debug.Console(2, this, "'{0}' is IBridgeAdvanced", device.Key);
var advDev = device as IBridgeAdvanced;
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.");
});
}
/// <summary>
/// Adds a join map
/// </summary>
/// <param name="deviceKey"></param>
/// <param name="joinMap"></param>
public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap)
{
if (!JoinMaps.ContainsKey(deviceKey))
{
JoinMaps.Add(deviceKey, joinMap);
}
else
{
Debug.Console(2, this, "Unable to add join map with key '{0}'. Key already exists in JoinMaps dictionary", deviceKey);
}
}
/// <summary>
/// Prints all the join maps on this bridge
/// </summary>
public void PrintJoinMaps()
{
Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X"));
foreach (var joinMap in JoinMaps)
{
Debug.Console(0, "Join map for device '{0}':", joinMap.Key);
joinMap.Value.PrintJoinMapInfo();
}
}
/// <summary>
/// Prints the join map for a device by key
/// </summary>
/// <param name="deviceKey"></param>
public void PrintJoinMapForDevice(string deviceKey)
{
var joinMap = JoinMaps[deviceKey];
if (joinMap == null)
{
Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
return;
}
Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
joinMap.PrintJoinMapInfo();
}
/// <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(1, this, "EiscApiAdvanced change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo == null) return;
Debug.Console(1, 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);
}
}
}

View 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;
}
}
}

View 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);
}
}
}
}

View 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);
}
}
}
}

View 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()
{
}
}
}

View 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));
}
*/
}
}
}

View 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]);
}
}
}

View File

@@ -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
}
}
}

View 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;
}
}
}
}

View 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();
}
}));
}
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
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:Core.Bridges.IBridge
{
}
}

View 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;
}
}
}
}

View 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));
}
}
}
}

View File

@@ -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;
}
}
}

View 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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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))
{
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,152 @@
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; }
#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
//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;
OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset;
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
}
}
}

View File

@@ -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;
}
}
}

View 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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

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

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View 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 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;
}
}
}

View File

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

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View 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;
}
}
}

View File

@@ -0,0 +1,65 @@
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.CrestronIO;
namespace PepperDash.Essentials.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);
}
}
}

View 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;
}
}
}
}

View File

@@ -0,0 +1,514 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using Crestron.SimplSharpPro.Diagnostics;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Room.MobileControl;
using Newtonsoft.Json;
namespace PepperDash.Essentials
{
public class ControlSystem : CrestronControlSystem
{
HttpLogoServer LogoServer;
private CTimer _startTimer;
private const long StartupTime = 500;
public ControlSystem()
: base()
{
Thread.MaxNumberOfUserThreads = 400;
Global.ControlSystem = this;
DeviceManager.Initialize(this);
}
/// <summary>
/// Entry point for the program
/// </summary>
public override void InitializeSystem()
{
_startTimer = new CTimer(StartSystem,StartupTime);
}
private void StartSystem(object obj)
{
DeterminePlatform();
if (Debug.DoNotLoadOnNextBoot)
{
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
ConsoleAccessLevelEnum.AccessOperator);
}
CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s);
}, "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse
("Current running configuration. This is the merged system and template configuration");
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
if (!Debug.DoNotLoadOnNextBoot)
GoWithLoad();
}
/// <summary>
/// Determines if the program is running on a processor (appliance) or server (VC-4).
///
/// Sets Global.FilePathPrefix and Global.ApplicationDirectoryPathPrefix based on platform
/// </summary>
public void DeterminePlatform()
{
try
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform....");
string filePathPrefix;
var dirSeparator = Global.DirectorySeparator;
string directoryPrefix;
directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory();
var fullVersion = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false);
AssemblyInformationalVersionAttribute fullVersionAtt = fullVersion[0] as AssemblyInformationalVersionAttribute;
Global.SetAssemblyVersion(fullVersionAtt.InformationalVersion);
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion);
// Check if User/ProgramX exists
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
{
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "User"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
}
// Check if Nvram/Programx exists
else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
{
Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
}
// If neither exists, set path to User/ProgramX
else
{
Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "User"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
}
}
else // Handles Linux OS (Virtual Control)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", Global.AssemblyVersion);
// Set path to User/
filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator;
}
Global.SetFilePathPrefix(filePathPrefix);
}
catch (Exception e)
{
Debug.Console(0, "Unable to Determine Platform due to Exception: {0}", e.Message);
}
}
/// <summary>
/// Begins the process of loading resources including plugins and configuration data
/// </summary>
public void GoWithLoad()
{
try
{
Debug.SetDoNotLoadOnNextBoot(false);
PluginLoader.AddProgramAssemblies();
new Core.DeviceFactory();
new Devices.Common.DeviceFactory();
new DM.DeviceFactory();
new DeviceFactory();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration");
var filesReady = SetupFilesystem();
if (filesReady)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins");
PluginLoader.LoadPlugins();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config...");
if (!ConfigReader.LoadConfig2())
return;
Load();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r" +
"-------------------------------------------------------------");
}
else
{
Debug.Console(0,
@"----------------------------------------------
------------------------------------------------
------------------------------------------------
Essentials file structure setup completed.
Please load config, sgd and ir files and
restart program.
------------------------------------------------
------------------------------------------------
------------------------------------------------");
}
}
catch (Exception e)
{
Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e);
}
// Notify the OS that the program intitialization has completed
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
}
/// <summary>
/// Verifies filesystem is set up. IR, SGD, and programX folders
/// </summary>
bool SetupFilesystem()
{
Debug.Console(0, "Verifying and/or creating folder structure");
var configDir = Global.FilePathPrefix;
var configExists = Directory.Exists(configDir);
if (!configExists)
Directory.Create(configDir);
var irDir = Global.FilePathPrefix + "ir";
if (!Directory.Exists(irDir))
Directory.Create(irDir);
var sgdDir = Global.FilePathPrefix + "sgd";
if (!Directory.Exists(sgdDir))
Directory.Create(sgdDir);
var pluginDir = Global.FilePathPrefix + "plugins";
if (!Directory.Exists(pluginDir))
Directory.Create(pluginDir);
return configExists;
}
/// <summary>
///
/// </summary>
public void TearDown()
{
Debug.Console(0, "Tearing down existing system");
DeviceManager.DeactivateAll();
TieLineCollection.Default.Clear();
foreach (var key in DeviceManager.GetDevices())
DeviceManager.RemoveDevice(key);
Debug.Console(0, "Tear down COMPLETE");
}
/// <summary>
///
/// </summary>
void Load()
{
LoadDevices();
LoadTieLines();
LoadRooms();
LoadLogoServer();
DeviceManager.ActivateAll();
LinkSystemMonitorToAppServer();
}
void LinkSystemMonitorToAppServer()
{
var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
var appServer = DeviceManager.GetDeviceForKey("appServer") as MobileControlSystemController;
if (sysMon != null && appServer != null)
{
var key = sysMon.Key + "-" + appServer.Key;
var messenger = new PepperDash.Essentials.AppServer.Messengers.SystemMonitorMessenger
(key, sysMon, "/device/systemMonitor");
messenger.RegisterWithAppServer(appServer);
DeviceManager.AddDevice(messenger);
}
}
/// <summary>
/// Reads all devices from config and adds them to DeviceManager
/// </summary>
public void LoadDevices()
{
// Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
// Add global System Monitor device
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
foreach (var devConf in ConfigReader.ConfigObject.Devices)
{
try
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}', type '{1}'", devConf.Key, devConf.Type);
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
{
if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower())
Debug.Console(0,
"WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available",
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
// Check if the processor is a DMPS model
if (this.ControllerPrompt.IndexOf("dmps", StringComparison.OrdinalIgnoreCase) > -1)
{
Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt);
var propertiesConfig = JsonConvert.DeserializeObject<DM.Config.DmpsRoutingPropertiesConfig>(devConf.Properties.ToString());
if(propertiesConfig == null)
propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig();
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig);
DeviceManager.AddDevice(dmpsRoutingController);
}
else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
{
Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController.");
var butToken = devConf.Properties["buttons"];
if (butToken != null)
{
var buttons = butToken.ToObject<Dictionary<string, Essentials.Core.Touchpanels.KeypadButton>>();
var tpController = new Essentials.Core.Touchpanels.Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons);
DeviceManager.AddDevice(tpController);
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key);
}
}
else
{
Debug.Console(2, "************Processor is not DMPS type***************");
}
continue;
}
// Try local factories first
IKeyed newDev = null;
if (newDev == null)
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
//
//if (newDev == null)
// newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
//
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded.");
}
/// <summary>
/// Helper method to load tie lines. This should run after devices have loaded
/// </summary>
public void LoadTieLines()
{
// In the future, we can't necessarily just clear here because devices
// might be making their own internal sources/tie lines
var tlc = TieLineCollection.Default;
//tlc.Clear();
if (ConfigReader.ConfigObject.TieLines == null)
{
return;
}
foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines)
{
var newTL = tieLineConfig.GetTieLine();
if (newTL != null)
tlc.Add(newTL);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Tie Lines Loaded.");
}
/// <summary>
/// Reads all rooms from config and adds them to DeviceManager
/// </summary>
public void LoadRooms()
{
if (ConfigReader.ConfigObject.Rooms == null)
{
Debug.Console(0, Debug.ErrorLogLevel.Warning, "WARNING: Configuration contains no rooms");
return;
}
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
if (room != null)
{
if (room is EssentialsHuddleSpaceRoom)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
// Mobile Control bridge
var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
DeviceManager.AddDevice(bridge);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
}
else if (room is EssentialsHuddleVtc1Room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
// Mobile Control bridge
var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
DeviceManager.AddDevice(bridge);
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
}
else
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
}
/// <summary>
/// Helps add the post activation steps that link bridges to main controller
/// </summary>
/// <param name="bridge"></param>
void AddBridgePostActivationHelper(MobileControlBridgeBase bridge)
{
bridge.AddPostActivationAction(() =>
{
var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
if (parent == null)
{
Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present");
return;
}
Debug.Console(0, bridge, "Linking to parent controller");
bridge.AddParent(parent);
parent.AddBridge(bridge);
});
}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
try
{
LogoServer = new HttpLogoServer(8080, Global.DirectorySeparator + "html" + Global.DirectorySeparator + "logo");
}
catch (Exception)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program");
}
}
}
}

View 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);
}
}
}

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