diff --git a/.DS_Store b/.DS_Store
index 84e855c..fc0cdb8 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 2828560..f4e10d9 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -69,6 +69,7 @@ jobs:
path: CHANGELOG.md
- name: Upload Release
id: create_release
+ if: steps.get_version.outputs.newVersion == 'true'
uses: ncipollo/release-action@v1
with:
allowUpdates: true
@@ -85,148 +86,148 @@ jobs:
echo "New Version: ${{ steps.get_version.outputs.newVersion }}" >> $GITHUB_STEP_SUMMARY
echo "Channel: ${{ steps.get_version.outputs.channel }}" >> $GITHUB_STEP_SUMMARY
echo "Type: ${{ steps.get_version.outputs.type }}" >> $GITHUB_STEP_SUMMARY
- Build_Project:
- runs-on: windows-2019
- needs: GetVersionNumber
- if: needs.GetVersionNumber.outputs.newVersion == 'true'
- env:
- VERSION: ${{ needs.GetVersionNumber.outputs.version }}
- steps:
- # First we checkout the source repo
- - name: Checkout repo
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- # Fetch all tags
- - name: Fetch tags
- run: git fetch --tags
- # Generate the appropriate version number
- # - name: Set Version Number
- # shell: powershell
- # run: |
- # $version = ./.github/scripts/GenerateVersionNumber.ps1
- # echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- # Use the version number to set the version of the assemblies
- - name: Update AssemblyInfo.cs
- shell: powershell
- run: |
- Write-Output ${{ env.VERSION }}
- ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- - name: restore Nuget Packages
- run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
- # Login to Docker
- - name: Login to Docker
- uses: azure/docker-login@v1
- with:
- username: ${{ secrets.DOCKERHUB_USER }}
- password: ${{ secrets.DOCKERHUB_PASSWORD }}
- # 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_PATH)$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
- # Zip up the output files as needed
- - name: Zip Build Output
- shell: powershell
- run: |
- $destination = "$($Env:GITHUB_HOME)\output"
- New-Item -ItemType Directory -Force -Path ($destination)
- Get-ChildItem ($destination)
- $exclusions = @("packages", "4-series")
- # 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", "*.nuspec" | ForEach-Object {
- $allowed = $true;
- # Exclude any files in submodules
- foreach ($exclude in $exclusions) {
- if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
- $allowed = $false;
- break;
- }
- }
- if ($allowed) {
- Write-Host "allowing $($_)"
- $_;
- }
- } | Copy-Item -Destination ($destination) -Force
- Write-Host "Getting matching files..."
- # Get any files from the output folder that match the following extensions
- Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object {
- # Replace the extensions with dll and xml and create an array
- $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml"))
- Write-Host "Filenames:"
- Write-Host $filenames
- if ($filenames.length -gt 0) {
- # Attempt to get the files and return them to the output directory
- Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
- }
- }
- Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" }
- Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force
- Write-Host "Output Contents post Zip"
- Get-ChildItem -Path $destination
- # 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 output files
- - name: Upload Build Output
- uses: actions/upload-artifact@v3
- with:
- name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- # Upload the Version file as an artifact
- - name: Upload version.txt
- uses: actions/upload-artifact@v3
- with:
- name: Version
- path: ${{env.GITHUB_HOME}}\output\version.txt
- # Create the release on the source repo
- - name: Get release notes
- uses: actions/download-artifact@v3
- with:
- name: change-log
- - name: Upload Release
- id: create_release
- uses: ncipollo/release-action@v1
- with:
- allowUpdates: true
- artifacts: 'output\*.*(zip)'
- prerelease: ${{ needs.GetVersionNumber.outputs.channel != '' }}
- tag: ${{ needs.GetVersionNumber.outputs.tag }}
- commit: ${{ github.sha }}
- bodyFile: ./CHANGELOG.md
- Push_Nuget_Package:
- needs: [GetVersionNumber, Build_Project]
- runs-on: windows-latest
- env:
- VERSION: ${{ needs.GetVersionNumber.outputs.version }}
- steps:
- - name: Download Build output
- uses: actions/download-artifact@v3
- with:
- name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION }}.zip
- path: ./
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- - name: Add nuget.exe
- uses: nuget/setup-nuget@v1
- - name: Add Github Packages source
- run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username pepperdash -password ${{ secrets.GITHUB_TOKEN }}
- - name: Create nuget package
- run: nuget pack "./epi-essentials-mobile-control.nuspec" -version ${{ env.VERSION }}
- - name: Publish nuget package to Github registry
- run: nuget push **/*.nupkg -source github
- - name: Add nuget.org API Key
- run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
- - name: Publish nuget package to nuget.org
- run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
+ # Build_Project:
+ # runs-on: windows-2019
+ # needs: GetVersionNumber
+ # if: needs.GetVersionNumber.outputs.newVersion == 'true'
+ # env:
+ # VERSION: ${{ needs.GetVersionNumber.outputs.version }}
+ # steps:
+ # # First we checkout the source repo
+ # - name: Checkout repo
+ # uses: actions/checkout@v4
+ # with:
+ # fetch-depth: 0
+ # # Fetch all tags
+ # - name: Fetch tags
+ # run: git fetch --tags
+ # # Generate the appropriate version number
+ # # - name: Set Version Number
+ # # shell: powershell
+ # # run: |
+ # # $version = ./.github/scripts/GenerateVersionNumber.ps1
+ # # echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
+ # # Use the version number to set the version of the assemblies
+ # - name: Update AssemblyInfo.cs
+ # shell: powershell
+ # run: |
+ # Write-Output ${{ env.VERSION }}
+ # ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
+ # - name: restore Nuget Packages
+ # run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
+ # # Login to Docker
+ # - name: Login to Docker
+ # uses: azure/docker-login@v1
+ # with:
+ # username: ${{ secrets.DOCKERHUB_USER }}
+ # password: ${{ secrets.DOCKERHUB_PASSWORD }}
+ # # 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_PATH)$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
+ # # Zip up the output files as needed
+ # - name: Zip Build Output
+ # shell: powershell
+ # run: |
+ # $destination = "$($Env:GITHUB_HOME)\output"
+ # New-Item -ItemType Directory -Force -Path ($destination)
+ # Get-ChildItem ($destination)
+ # $exclusions = @("packages", "4-series")
+ # # 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", "*.nuspec" | ForEach-Object {
+ # $allowed = $true;
+ # # Exclude any files in submodules
+ # foreach ($exclude in $exclusions) {
+ # if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
+ # $allowed = $false;
+ # break;
+ # }
+ # }
+ # if ($allowed) {
+ # Write-Host "allowing $($_)"
+ # $_;
+ # }
+ # } | Copy-Item -Destination ($destination) -Force
+ # Write-Host "Getting matching files..."
+ # # Get any files from the output folder that match the following extensions
+ # Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object {
+ # # Replace the extensions with dll and xml and create an array
+ # $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml"))
+ # Write-Host "Filenames:"
+ # Write-Host $filenames
+ # if ($filenames.length -gt 0) {
+ # # Attempt to get the files and return them to the output directory
+ # Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
+ # }
+ # }
+ # Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" }
+ # Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force
+ # Write-Host "Output Contents post Zip"
+ # Get-ChildItem -Path $destination
+ # # 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 output files
+ # - name: Upload Build Output
+ # uses: actions/upload-artifact@v3
+ # with:
+ # name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
+ # path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
+ # # Upload the Version file as an artifact
+ # - name: Upload version.txt
+ # uses: actions/upload-artifact@v3
+ # with:
+ # name: Version
+ # path: ${{env.GITHUB_HOME}}\output\version.txt
+ # # Create the release on the source repo
+ # - name: Get release notes
+ # uses: actions/download-artifact@v3
+ # with:
+ # name: change-log
+ # - name: Upload Release
+ # id: create_release
+ # uses: ncipollo/release-action@v1
+ # with:
+ # allowUpdates: true
+ # artifacts: 'output\*.*(zip)'
+ # prerelease: ${{ needs.GetVersionNumber.outputs.channel != '' }}
+ # tag: ${{ needs.GetVersionNumber.outputs.tag }}
+ # commit: ${{ github.sha }}
+ # bodyFile: ./CHANGELOG.md
+ # Push_Nuget_Package:
+ # needs: [GetVersionNumber, Build_Project]
+ # runs-on: windows-latest
+ # env:
+ # VERSION: ${{ needs.GetVersionNumber.outputs.version }}
+ # steps:
+ # - name: Download Build output
+ # uses: actions/download-artifact@v3
+ # with:
+ # name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION }}.zip
+ # path: ./
+ # - name: Unzip Build file
+ # run: |
+ # Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
+ # Remove-Item -Path .\*.zip
+ # - name: Copy Files to root & delete output directory
+ # run: |
+ # Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
+ # Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
+ # Remove-Item -Path .\output -Recurse
+ # - name: Add nuget.exe
+ # uses: nuget/setup-nuget@v1
+ # - name: Add Github Packages source
+ # run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username pepperdash -password ${{ secrets.GITHUB_TOKEN }}
+ # - name: Create nuget package
+ # run: nuget pack "./epi-essentials-mobile-control.nuspec" -version ${{ env.VERSION }}
+ # - name: Publish nuget package to Github registry
+ # run: nuget push **/*.nupkg -source github
+ # - name: Add nuget.org API Key
+ # run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
+ # - name: Publish nuget package to nuget.org
+ # run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
Build_Project_4-Series:
needs: GetVersionNumber
if: needs.GetVersionNumber.outputs.newVersion == 'true'
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
deleted file mode 100644
index b7a2fa0..0000000
--- a/.github/workflows/main.yml
+++ /dev/null
@@ -1,300 +0,0 @@
-name: Main Build using Docker
-
-on:
- release:
- types:
- - created
- branches:
- - main
-env:
- # solution path doesn't need slashes unless there it is multiple folders deep
- # solution name does not include extension. .sln is assumed
- SOLUTION_PATH: 3-series\
- SOLUTION_FILE: epi-essentials-mobile-control
- # 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
- with:
- fetch-depth: 0
- # Generate the appropriate version number
- - name: Set Version Number
- shell: powershell
- env:
- TAG_NAME: ${{ github.event.release.tag_name }}
- run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- # Use the version number to set the version of the assemblies
- - name: Update AssemblyInfo.cs
- shell: powershell
- run: |
- Write-Output ${{ env.VERSION }}
- ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- - name: restore Nuget Packages
- run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
- # Login to Docker
- - name: Login to Docker
- uses: azure/docker-login@v1
- with:
- username: ${{ secrets.DOCKERHUB_USER }}
- password: ${{ secrets.DOCKERHUB_PASSWORD }}
- # 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_PATH)\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
- # Zip up the output files as needed
- - name: Zip Build Output
- shell: powershell
- run: |
- $destination = "$($Env:GITHUB_HOME)\output"
- New-Item -ItemType Directory -Force -Path ($destination)
- Get-ChildItem ($destination)
- $exclusions = @("packages", "4-series")
- # 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", "*.nuspec" | ForEach-Object {
- $allowed = $true;
- # Exclude any files in submodules
- foreach ($exclude in $exclusions) {
- if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
- $allowed = $false;
- break;
- }
- }
- if ($allowed) {
- Write-Host "allowing $($_)"
- $_;
- }
- } | Copy-Item -Destination ($destination) -Force
- Write-Host "Getting matching files..."
- # Get any files from the output folder that match the following extensions
- Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object {
- # Replace the extensions with dll and xml and create an array
- $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml"))
- Write-Host "Filenames:"
- Write-Host $filenames
- if ($filenames.length -gt 0) {
- # Attempt to get the files and return them to the output directory
- Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
- }
- }
- Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" }
- Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force
- Write-Host "Output Contents post Zip"
- Get-ChildItem -Path $destination
- # 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"
- - name: Upload Build Output
- uses: actions/upload-artifact@v3
- with:
- name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- # Upload the Version file as an artifact
- - name: Upload version.txt
- uses: actions/upload-artifact@v3
- with:
- name: Version
- path: ${{env.GITHUB_HOME}}\output\version.txt
- # Upload the build package to the release
- - name: Upload Release Package
- id: upload_release
- uses: actions/upload-release-asset@v1
- with:
- upload_url: ${{ github.event.release.upload_url }}
- asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- asset_content_type: application/zip
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- Push_Nuget_Package:
- needs: Build_Project
- runs-on: windows-latest
- steps:
- - name: Download Build Version Info
- uses: actions/download-artifact@v3
- with:
- name: Version
- path: Version
- - name: Set Version Number
- shell: powershell
- run: |
- Get-ChildItem "./Version"
- $version = Get-Content -Path ./Version/version.txt
- Write-Host "Version: $version"
- echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- Remove-Item -Path ./Version/version.txt
- Remove-Item -Path ./Version
- - name: Download Build output
- uses: actions/download-artifact@v3
- with:
- name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
- path: ./
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- - name: Add nuget.exe
- uses: nuget/setup-nuget@v1
- - name: Add Github Packages source
- run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
- - name: Create nuget package
- run: nuget pack "./epi-essentials-mobile-control.nuspec" -version ${{ env.VERSION }}
- - name: Publish nuget package to Github registry
- run: nuget push **/*.nupkg -source github
- - name: Add nuget.org API Key
- run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
- - name: Publish nuget package to nuget.org
- run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
- Build_Project_4-Series:
- runs-on: windows-latest
- steps:
- # First we checkout the source repo
- - name: Checkout repo
- uses: actions/checkout@v3
- with:
- fetch-depth: 0
- # Generate the appropriate version number
- - name: Set Version Number
- shell: powershell
- env:
- TAG_NAME: ${{ github.event.release.tag_name }}
- run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- # Use the version number to set the version of the assemblies
- - name: Update AssemblyInfo.cs
- shell: powershell
- run: |
- Write-Output ${{ env.VERSION }}
- ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- - name: Setup MS-Build
- uses: microsoft/setup-msbuild@v1
- - name: restore Nuget Packages
- run: nuget restore ./4-series/$($Env:SOLUTION_FILE).sln
- # Build the solutions in the docker image
- - name: Build Solution
- shell: powershell
- run: |
- msbuild ./4-series/$($Env:SOLUTION_FILE).sln /p:platform="Any CPU" /p:configuration="Release"
- # Zip up the output files as needed
- - name: Zip Build Output
- shell: powershell
- run: |
- $destination = "$($Env:GITHUB_HOME)\output"
- New-Item -ItemType Directory -Force -Path ($destination)
- Get-ChildItem ($destination)
- $exclusions = @("packages", "3-series")
- # 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", "*.nuspec" | ForEach-Object {
- $allowed = $true;
- # Exclude any files in submodules
- foreach ($exclude in $exclusions) {
- if ((Split-Path $_.FullName -Parent).contains("$($exclude)")) {
- $allowed = $false;
- break;
- }
- }
- if ($allowed) {
- Write-Host "allowing $($_)"
- $_;
- }
- } | Copy-Item -Destination ($destination) -Force
- Write-Host "Getting matching files..."
- # Get any files from the output folder that match the following extensions
- Get-ChildItem -Path $destination | Where-Object {($_.Extension -eq ".clz") -or ($_.Extension -eq ".cpz" -or ($_.Extension -eq ".cplz"))} | ForEach-Object {
- # Replace the extensions with dll and xml and create an array
- $filenames = @($($_ -replace "cpz|clz|cplz", "dll"), $($_ -replace "cpz|clz|cplz", "xml"))
- Write-Host "Filenames:"
- Write-Host $filenames
- if ($filenames.length -gt 0) {
- # Attempt to get the files and return them to the output directory
- Get-ChildItem -Recurse -Path "$($Env:GITHUB_WORKSPACE)" -include $filenames | Copy-Item -Destination ($destination) -Force
- }
- }
- Get-ChildItem -Path $destination\*.cplz | Rename-Item -NewName { "$($_.BaseName)-4s-$($Env:VERSION)$($_.Extension)" }
- Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-4s-$($Env:VERSION).zip" -Force
- Write-Host "Output Contents post Zip"
- Get-ChildItem -Path $destination
- # 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"
- - name: Upload Build Output
- uses: actions/upload-artifact@v3
- with:
- name: ${{ env.SOLUTION_FILE}}-4s-${{ env.VERSION}}.zip
- path: ./${{ env.SOLUTION_FILE}}-4s-${{ env.VERSION}}.zip
- # Upload the Version file as an artifact
- - name: Upload version.txt
- uses: actions/upload-artifact@v3
- 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}}-4s-${{ env.VERSION}}.zip
- asset_name: ${{ env.SOLUTION_FILE}}-4s-${{ env.VERSION}}.zip
- asset_content_type: application/zip
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- Push_Nuget_Package_4-Series:
- needs: Build_Project_4-Series
- runs-on: windows-latest
- steps:
- - name: Download Build Version Info
- uses: actions/download-artifact@v3
- with:
- name: Version
- path: Version
- - name: Set Version Number
- shell: powershell
- run: |
- Get-ChildItem "./Version"
- $version = Get-Content -Path ./Version/version.txt
- Write-Host "Version: $version"
- echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- Remove-Item -Path ./Version/version.txt
- Remove-Item -Path ./Version
- - name: Download Build output
- uses: actions/download-artifact@v3
- with:
- name: ${{ env.SOLUTION_FILE}}-4s-${{ env.VERSION}}.zip
- path: ./
- - name: Unzip Build file
- run: |
- Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
- Remove-Item -Path .\*.zip
- - name: Copy Files to root & delete output directory
- run: |
- Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
- Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
- Remove-Item -Path .\output -Recurse
- - name: Add nuget.exe
- uses: nuget/setup-nuget@v1
- - name: Add Github Packages source
- run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
- - name: Create nuget package
- run: nuget pack "./epi-essentials-mobile-control.nuspec" -version ${{ env.VERSION }}
- - name: Publish nuget package to Github registry
- run: nuget push **/*.nupkg -source github
- - name: Add nuget.org API Key
- run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
- - name: Publish nuget package to nuget.org
- run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
diff --git a/.gitignore b/.gitignore
index 9394468..4115880 100644
--- a/.gitignore
+++ b/.gitignore
@@ -362,3 +362,4 @@ MigrationBackup/
# Build Outputs
output/
+/exampleConfigs/essentials-mc-test-configurationFile.json
diff --git a/3-series/Messengers/AudioCodecBaseMessenger.cs b/3-series/Messengers/AudioCodecBaseMessenger.cs
index b0fbbc9..0472241 100644
--- a/3-series/Messengers/AudioCodecBaseMessenger.cs
+++ b/3-series/Messengers/AudioCodecBaseMessenger.cs
@@ -1,9 +1,9 @@
-using System;
-using System.Linq;
-using PepperDash.Essentials.Devices.Common.Codec;
-using PepperDash.Essentials.Devices.Common.AudioCodec;
-
+using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Devices.Common.AudioCodec;
+using PepperDash.Essentials.Devices.Common.Codec;
+using System;
+using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -24,45 +24,62 @@ public class AudioCodecBaseMessenger : MessengerBase
///
///
public AudioCodecBaseMessenger(string key, AudioCodecBase codec, string messagePath)
- : base(key, messagePath)
+ : base(key, messagePath, codec)
{
- if (codec == null)
- throw new ArgumentNullException("codec");
-
- Codec = codec;
- codec.CallStatusChange += codec_CallStatusChange;
+ Codec = codec ?? throw new ArgumentNullException("codec");
+ codec.CallStatusChange += Codec_CallStatusChange;
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendAtcFullMessageObject));
- appServerController.AddAction(MessagePath + "/dial", new Action(s => Codec.Dial(s)));
- appServerController.AddAction(MessagePath + "/endCallById", new Action(s =>
+ AddAction("/fullStatus", (id, content) => SendAtcFullMessageObject());
+ AddAction("/dial", (id, content) =>
{
- var call = GetCallWithId(s);
+ var msg = content.ToObject>();
+
+ Codec.Dial(msg.Value);
+ });
+
+ AddAction("/endCallById", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ var call = GetCallWithId(msg.Value);
if (call != null)
Codec.EndCall(call);
- }));
- appServerController.AddAction(MessagePath + "/endAllCalls", new Action(Codec.EndAllCalls));
- appServerController.AddAction(MessagePath + "/dtmf", new Action(s => Codec.SendDtmf(s)));
- appServerController.AddAction(MessagePath + "/rejectById", new Action(s =>
+ });
+
+ AddAction("/endAllCalls", (id, content) => Codec.EndAllCalls());
+ AddAction("/dtmf", (id, content) =>
{
- var call = GetCallWithId(s);
+ var msg = content.ToObject>();
+
+ Codec.SendDtmf(msg.Value);
+ });
+
+ AddAction("/rejectById", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ var call = GetCallWithId(msg.Value);
+
if (call != null)
Codec.RejectCall(call);
- }));
- appServerController.AddAction(MessagePath + "/acceptById", new Action(s =>
+ });
+
+ AddAction("/acceptById", (id, content) =>
{
- var call = GetCallWithId(s);
+ var msg = content.ToObject>();
+ var call = GetCallWithId(msg.Value);
if (call != null)
Codec.AcceptCall(call);
- }));
+ });
}
///
@@ -75,7 +92,7 @@ private CodecActiveCallItem GetCallWithId(string id)
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
}
- private void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
SendAtcFullMessageObject();
}
@@ -87,15 +104,17 @@ private void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEven
private void SendAtcFullMessageObject()
{
var info = Codec.CodecInfo;
- PostStatusMessage(new
- {
- isInCall = Codec.IsInCall,
- calls = Codec.ActiveCalls,
- info = new
+
+ PostStatusMessage(JToken.FromObject(new
{
- phoneNumber = info.PhoneNumber
- }
- });
+ isInCall = Codec.IsInCall,
+ calls = Codec.ActiveCalls,
+ info = new
+ {
+ phoneNumber = info.PhoneNumber
+ }
+ })
+ );
}
}
}
\ No newline at end of file
diff --git a/3-series/Messengers/CameraBaseMessenger.cs b/3-series/Messengers/CameraBaseMessenger.cs
index 05c31a6..1a8f070 100644
--- a/3-series/Messengers/CameraBaseMessenger.cs
+++ b/3-series/Messengers/CameraBaseMessenger.cs
@@ -1,8 +1,9 @@
-using System;
-using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -20,143 +21,173 @@ public class CameraBaseMessenger : MessengerBase
///
///
public CameraBaseMessenger(string key, CameraBase camera, string messagePath)
- : base(key, messagePath)
+ : base(key, messagePath, camera)
{
- if (camera == null)
- throw new ArgumentNullException("camera");
+ Camera = camera ?? throw new ArgumentNullException("camera");
- Camera = camera;
- var presetsCamera = Camera as IHasCameraPresets;
-
- if (presetsCamera != null)
+ if (Camera is IHasCameraPresets presetsCamera)
{
- presetsCamera.PresetsListHasChanged += presetsCamera_PresetsListHasChanged;
+ presetsCamera.PresetsListHasChanged += PresetsCamera_PresetsListHasChanged;
}
}
- private void presetsCamera_PresetsListHasChanged(object sender, EventArgs e)
+ private void PresetsCamera_PresetsListHasChanged(object sender, EventArgs e)
{
- var presetsCamera = Camera as IHasCameraPresets;
-
var presetList = new List();
- if (presetsCamera != null)
+ if (Camera is IHasCameraPresets presetsCamera)
presetList = presetsCamera.Presets;
- PostStatusMessage(new
- {
- presets = presetList
- });
+ PostStatusMessage(JToken.FromObject(new
+ {
+ presets = presetList
+ })
+ );
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendCameraFullMessageObject));
+ AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
- var ptzCamera = Camera as IHasCameraPtzControl;
- if (ptzCamera != null)
+ if (Camera is IHasCameraPtzControl ptzCamera)
{
// 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 =>
+ AddAction("/cameraUp", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
+ {
ptzCamera.TiltUp();
- else
- ptzCamera.TiltStop();
+ return;
+ }
+
+ ptzCamera.TiltStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction(b =>
+ AddAction("/cameraDown", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
+ {
ptzCamera.TiltDown();
- else
- ptzCamera.TiltStop();
+ return;
+ }
+
+ ptzCamera.TiltStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction(b =>
+ AddAction("/cameraLeft", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
+ {
ptzCamera.PanLeft();
- else
- ptzCamera.PanStop();
+ return;
+ }
+
+ ptzCamera.PanStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction(b =>
+ AddAction("/cameraRight", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
+ {
ptzCamera.PanRight();
- else
- ptzCamera.PanStop();
+ return;
+ }
+
+ ptzCamera.PanStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction(b =>
+ AddAction("/cameraZoomIn", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
+ {
ptzCamera.ZoomIn();
- else
- ptzCamera.ZoomStop();
+ return;
+ }
+
+ ptzCamera.ZoomStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction(b =>
+ AddAction("/cameraZoomOut", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
if (b)
+ {
ptzCamera.ZoomOut();
- else
- ptzCamera.ZoomStop();
+ return;
+ }
+
+ 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));
+ AddAction("/cameraModeAuto", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOn());
+
+ AddAction("/cameraModeManual", (id, content) => (Camera as IHasCameraAutoMode).CameraAutoModeOff());
+
}
if (Camera is IHasPowerControl)
{
- appServerController.AddAction(MessagePath + "/cameraModeOff", new Action((Camera as IHasPowerControl).PowerOff));
- appServerController.AddAction(MessagePath + "/cameraModeManual", new Action((Camera as IHasPowerControl).PowerOn));
+ AddAction("/cameraModeOff", (id, content) => (Camera as IHasPowerControl).PowerOff());
+ AddAction("/cameraModeManual", (id, content) => (Camera as IHasPowerControl).PowerOn());
}
- var presetsCamera = Camera as IHasCameraPresets;
- if (presetsCamera != null)
+ if (Camera is IHasCameraPresets presetsCamera)
{
for (int i = 1; i <= 6; i++)
{
var preset = i;
- appServerController.AddAction(MessagePath + "/cameraPreset" + i,
- new Action(p => presetsCamera.PresetSelect(preset)));
+ AddAction("/cameraPreset" + i, (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ presetsCamera.PresetSelect(msg.Value);
+ });
+
}
}
}
+ private void HandleCameraPressAndHold(JToken content, Action cameraAction)
+ {
+ var state = content.ToObject>();
+
+ var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
+ if (timerHandler == null)
+ {
+ return;
+ }
+
+ timerHandler(state.Value, cameraAction);
+
+ cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
+ }
+
///
/// Helper method to update the full status of the camera
///
private void SendCameraFullMessageObject()
{
- var presetsCamera = Camera as IHasCameraPresets;
-
var presetList = new List();
- if (presetsCamera != null)
+ if (Camera is IHasCameraPresets presetsCamera)
presetList = presetsCamera.Presets;
- PostStatusMessage(new
- {
- cameraManualSupported = Camera is IHasCameraControls,
- cameraAutoSupported = Camera is IHasCameraAutoMode,
- cameraOffSupported = Camera is IHasCameraOff,
- cameraMode = GetCameraMode(),
- hasPresets = Camera is IHasCameraPresets,
- presets = presetList
- });
+ PostStatusMessage(JToken.FromObject(new
+ {
+ cameraManualSupported = Camera is IHasCameraControls,
+ cameraAutoSupported = Camera is IHasCameraAutoMode,
+ cameraOffSupported = Camera is IHasCameraOff,
+ cameraMode = GetCameraMode(),
+ hasPresets = Camera is IHasCameraPresets,
+ presets = presetList
+ })
+ );
}
///
diff --git a/3-series/Messengers/CommMonitorMessenger.cs b/3-series/Messengers/CommMonitorMessenger.cs
index 93cb411..6e6ded7 100644
--- a/3-series/Messengers/CommMonitorMessenger.cs
+++ b/3-series/Messengers/CommMonitorMessenger.cs
@@ -1,6 +1,8 @@
-using System;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -12,12 +14,8 @@ public class CommMonitorMessenger : MessengerBase
private readonly ICommunicationMonitor _monitor;
- public CommMonitorMessenger(string key, string messagePath) : base(key, messagePath)
- {
- }
-
public CommMonitorMessenger(string key, string messagePath, ICommunicationMonitor monitor)
- : this(key, messagePath)
+ : base(key, messagePath, monitor as Device)
{
_monitor = monitor;
}
@@ -26,15 +24,14 @@ private void SendStatus()
{
var messageObj = new
{
- commMonitor = new {
+ commMonitor = new
+ {
online = _monitor.CommunicationMonitor.IsOnline,
status = _monitor.CommunicationMonitor.Status.ToString()
}
};
-
-
- PostStatusMessage(messageObj);
+ AppSer(messageObj);
}
#region Overrides of MessengerBase
@@ -45,23 +42,24 @@ protected override void CustomRegisterWithAppServer(IMobileControl3 appServerCon
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendStatus));
-
+ appServerController.AddAction(MessagePath + "/fullStatus", (id, content) => SendStatus());
+
_monitor.CommunicationMonitor.IsOnlineFeedback.OutputChange += IsOnlineFeedbackOnOutputChange;
_monitor.CommunicationMonitor.StatusChange += CommunicationMonitorOnStatusChange;
}
private void CommunicationMonitorOnStatusChange(object sender, MonitorStatusChangeEventArgs monitorStatusChangeEventArgs)
{
- var messageObj = new
+ var messageObj = new MobileControlMessage
{
- type = MessagePath + PollStatusPath,
- content = new
+ Type = MessagePath + PollStatusPath,
+ Content = JToken.FromObject(new
{
- commMonitor = new {
+ commMonitor = new
+ {
status = monitorStatusChangeEventArgs.Status.ToString()
}
- }
+ })
};
AppServerController.SendMessageObject(messageObj);
@@ -69,15 +67,16 @@ private void CommunicationMonitorOnStatusChange(object sender, MonitorStatusChan
private void IsOnlineFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
- var messageObj = new
+ var messageObj = new MobileControlMessage
{
- type = MessagePath + OnlineStatusPath,
- content = new
+ Type = MessagePath + OnlineStatusPath,
+ Content = JToken.FromObject(new
{
- commMonitor = new {
+ commMonitor = new
+ {
online = feedbackEventArgs.BoolValue
}
- }
+ })
};
AppServerController.SendMessageObject(messageObj);
diff --git a/3-series/Messengers/DevicePresetsModelMessenger.cs b/3-series/Messengers/DevicePresetsModelMessenger.cs
index eff0a1b..8b1db5b 100644
--- a/3-series/Messengers/DevicePresetsModelMessenger.cs
+++ b/3-series/Messengers/DevicePresetsModelMessenger.cs
@@ -1,38 +1,28 @@
-using System;
-using System.Collections.Generic;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.Presets;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class DevicePresetsModelMessenger:MessengerBase
+ public class DevicePresetsModelMessenger : MessengerBase
{
private readonly ITvPresetsProvider _presetsDevice;
- public DevicePresetsModelMessenger(string key, string messagePath) : base(key, messagePath)
- {
-
- }
-
public DevicePresetsModelMessenger(string key, string messagePath, ITvPresetsProvider presetsDevice)
- : this(key, messagePath)
+ : base(key, messagePath, presetsDevice as Device)
{
_presetsDevice = presetsDevice;
}
- private void TvPresetsOnPresetChanged(ISetTopBoxNumericKeypad device, string channel)
- {
- throw new NotImplementedException();
- }
-
private void SendPresets()
{
- PostStatusMessage(new
+ PostStatusMessage(new PresetStateMessage
{
- favorites = _presetsDevice.TvPresets.PresetsList
+ Favorites = _presetsDevice.TvPresets.PresetsList
});
}
@@ -41,34 +31,42 @@ private void RecallPreset(ISetTopBoxNumericKeypad device, string channel)
_presetsDevice.TvPresets.Dial(channel, device);
}
- private void SavePresets(List presets )
+ private void SavePresets(List presets)
{
_presetsDevice.TvPresets.UpdatePresets(presets);
}
-
+
#region Overrides of MessengerBase
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendPresets));
- appServerController.AddAction(MessagePath + "/recall", new Action((p) =>
+ AddAction("/fullStatus", (id, content) => SendPresets());
+
+ AddAction("/recall", (id, content) =>
{
- var dev = DeviceManager.GetDeviceForKey(p.DeviceKey) as ISetTopBoxNumericKeypad;
+ var p = content.ToObject();
+
- if (dev == null)
+ if (!(DeviceManager.GetDeviceForKey(p.DeviceKey) is ISetTopBoxNumericKeypad dev))
{
Debug.Console(1, "Unable to find device with key {0}", p.DeviceKey);
return;
}
RecallPreset(dev, p.Preset.Channel);
- }));
- appServerController.AddAction(MessagePath + "/save", new Action>(SavePresets));
+ });
+
+ AddAction("/save", (id, content) =>
+ {
+ var presets = content.ToObject>();
+
+ SavePresets(presets);
+ });
_presetsDevice.TvPresets.PresetsSaved += (p) => SendPresets();
}
@@ -84,4 +82,10 @@ public class PresetChannelMessage
[JsonProperty("deviceKey")]
public string DeviceKey;
}
+
+ public class PresetStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("favorites", NullValueHandling = NullValueHandling.Ignore)]
+ public List Favorites { get; set; } = new List();
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/DeviceVolumeMessenger.cs b/3-series/Messengers/DeviceVolumeMessenger.cs
index b558cff..44ef611 100644
--- a/3-series/Messengers/DeviceVolumeMessenger.cs
+++ b/3-series/Messengers/DeviceVolumeMessenger.cs
@@ -1,83 +1,157 @@
-using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using static Crestron.SimplSharpPro.Lighting.ZumWired.ZumNetBridgeRoom.ZumWiredRoomInterface;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class DeviceVolumeMessenger:MessengerBase
+ public class DeviceVolumeMessenger : MessengerBase
{
- private IBasicVolumeWithFeedback _device;
- private string _deviceKey;
+ private readonly IBasicVolumeWithFeedback _localDevice;
public DeviceVolumeMessenger(string key, string messagePath) : base(key, messagePath)
{
}
- public DeviceVolumeMessenger(string key, string messagePath, string deviceKey, IBasicVolumeWithFeedback device)
- : this(key, messagePath)
+ public DeviceVolumeMessenger(string key, string messagePath, IBasicVolumeWithFeedback device)
+ : base(key, messagePath, device as PepperDash.Core.Device)
{
- _device = device;
- _deviceKey = deviceKey;
+ _localDevice = device;
}
private void SendStatus()
{
- var messageObj = new
+ var messageObj = new VolumeStateMessage
{
- volume = new
+ Volume = new Volume
{
- level = _device.VolumeLevelFeedback.IntValue,
- muted = _device.MuteFeedback.BoolValue,
+ Level = _localDevice.VolumeLevelFeedback.IntValue,
+ Muted = _localDevice.MuteFeedback.BoolValue,
+ HasMute = true, // assume all devices have mute for now
}
};
+ if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
+ {
+ messageObj.Volume.RawValue = volumeAdvanced.RawVolumeLevel.ToString();
+ messageObj.Volume.Units = volumeAdvanced.Units;
+ }
+
PostStatusMessage(messageObj);
}
#region Overrides of MessengerBase
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendStatus));
- appServerController.AddAction(MessagePath + "/level", new Action(_device.SetVolume));
+ AddAction("/fullStatus", (id, content) => SendStatus());
- appServerController.AddAction(MessagePath + "/muteToggle", new Action(
- (b) => {
- if(b){
- _device.MuteToggle();
- }}));
+ AddAction("/level", (id, content) =>
+ {
+ var volume = content.ToObject>();
- _device.MuteFeedback.OutputChange += (sender, args) =>
+ _localDevice.SetVolume(volume.Value);
+ });
+
+ AddAction("/muteToggle", (id, content) =>
{
- var messageObj = new
- {
- volume = new
- {
- muted = args.BoolValue
- }
- };
+ var state = content.ToObject>();
+
+ if (!state.Value) return;
+
+ _localDevice.MuteToggle();
+ });
+
+ AddAction("/muteOn", (id, content) =>
+ {
+ _localDevice.MuteOn();
+ });
+
+ AddAction("/muteOff", (id, content) =>
+ {
+ _localDevice.MuteOff();
+ });
+
+ AddAction("/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) =>
+ {
+ _localDevice.VolumeUp(b);
+ }));
+
+
- PostStatusMessage(messageObj);
+ AddAction("/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => _localDevice.VolumeDown(b)));
+
+ _localDevice.MuteFeedback.OutputChange += (sender, args) =>
+ {
+ PostStatusMessage(JToken.FromObject(
+ new
+ {
+ volume = new
+ {
+ muted = args.BoolValue
+ }
+ })
+ );
};
- _device.VolumeLevelFeedback.OutputChange += (sender, args) =>
+ _localDevice.VolumeLevelFeedback.OutputChange += (sender, args) =>
{
- var messageObj = new
+ var rawValue = "";
+ if (_localDevice is IBasicVolumeWithFeedbackAdvanced volumeAdvanced)
+ {
+ rawValue = volumeAdvanced.RawVolumeLevel.ToString();
+ }
+
+ var message = new
{
volume = new
{
- level = args.IntValue
+ level = args.IntValue,
+ rawValue
}
};
- PostStatusMessage(messageObj);
+ PostStatusMessage(JToken.FromObject(message));
};
+
+
}
#endregion
}
+
+ public class VolumeStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("volume", NullValueHandling = NullValueHandling.Ignore)]
+ public Volume Volume { get; set; }
+ }
+
+ public class Volume
+ {
+ [JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
+ public int? Level { get; set; }
+
+ [JsonProperty("hasMute", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? HasMute { get; set; }
+
+ [JsonProperty("muted", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? Muted { get; set; }
+
+ [JsonProperty("label", NullValueHandling = NullValueHandling.Ignore)]
+ public string Label { get; set; }
+
+ [JsonProperty("rawValue", NullValueHandling = NullValueHandling.Ignore)]
+ public string RawValue { get; set; }
+
+ [JsonConverter(typeof(StringEnumConverter))]
+ [JsonProperty("units", NullValueHandling = NullValueHandling.Ignore)]
+ public eVolumeLevelUnits? Units { get; set; }
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/GenericMessenger.cs b/3-series/Messengers/GenericMessenger.cs
index 51c4fcc..2a52db1 100644
--- a/3-series/Messengers/GenericMessenger.cs
+++ b/3-series/Messengers/GenericMessenger.cs
@@ -1,32 +1,24 @@
using PepperDash.Essentials.Core;
-using System;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class GenericMessenger : MessengerBase
{
- private EssentialsDevice _device;
-
- public GenericMessenger(string key, EssentialsDevice device, string messagePath):base(key, messagePath, device)
+ public GenericMessenger(string key, EssentialsDevice device, string messagePath) : base(key, messagePath, device)
{
- if(device == null)
- {
- throw new ArgumentNullException("device");
- }
-
- _device = device;
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
- appServerController.AddAction(string.Format("{0}/fullStatus", MessagePath), new Action(SendFullStatus));
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
}
private void SendFullStatus()
diff --git a/3-series/Messengers/IHasScheduleAwarenessMessenger.cs b/3-series/Messengers/IHasScheduleAwarenessMessenger.cs
index 4d0a04e..056f2f2 100644
--- a/3-series/Messengers/IHasScheduleAwarenessMessenger.cs
+++ b/3-series/Messengers/IHasScheduleAwarenessMessenger.cs
@@ -1,10 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using PepperDash.Essentials.Devices.Common.Codec;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Devices.Common.Codec;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -13,41 +13,36 @@ public class IHasScheduleAwarenessMessenger : MessengerBase
public IHasScheduleAwareness ScheduleSource { get; private set; }
public IHasScheduleAwarenessMessenger(string key, IHasScheduleAwareness scheduleSource, string messagePath)
- :base(key, messagePath)
+ : base(key, messagePath, scheduleSource as Device)
{
- if (scheduleSource == null)
- {
- throw new ArgumentNullException("scheduleSource");
- }
-
- ScheduleSource = scheduleSource;
+ ScheduleSource = scheduleSource ?? throw new ArgumentNullException("scheduleSource");
ScheduleSource.CodecSchedule.MeetingsListHasChanged += new EventHandler(CodecSchedule_MeetingsListHasChanged);
ScheduleSource.CodecSchedule.MeetingEventChange += new EventHandler(CodecSchedule_MeetingEventChange);
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullScheduleObject));
-
+ AddAction("/schedule/fullStatus", (id, content) => SendFullScheduleObject());
}
- void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e)
+ private void CodecSchedule_MeetingEventChange(object sender, MeetingEventArgs e)
{
- PostStatusMessage(new
- {
- meetingChange = new
+ PostStatusMessage(JToken.FromObject(new MeetingChangeMessage
{
- changeType = e.ChangeType.ToString(),
- meeting = e.Meeting
- }
- });
+ MeetingChange = new MeetingChange
+ {
+ ChangeType = e.ChangeType.ToString(),
+ Meeting = e.Meeting
+ }
+ })
+ );
}
- void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e)
+ private void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e)
{
SendFullScheduleObject();
}
@@ -57,11 +52,35 @@ void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e)
///
private void SendFullScheduleObject()
{
- PostStatusMessage(new
- {
- meetings = ScheduleSource.CodecSchedule.Meetings,
- meetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes
- });
+ PostStatusMessage(new FullScheduleMessage
+ {
+ Meetings = ScheduleSource.CodecSchedule.Meetings,
+ MeetingWarningMinutes = ScheduleSource.CodecSchedule.MeetingWarningMinutes
+ });
}
}
+
+ public class FullScheduleMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("meetings", NullValueHandling = NullValueHandling.Ignore)]
+ public List Meetings { get; set; }
+
+ [JsonProperty("meetingWarningMinutes", NullValueHandling = NullValueHandling.Ignore)]
+ public int MeetingWarningMinutes { get; set; }
+ }
+
+ public class MeetingChangeMessage
+ {
+ [JsonProperty("meetingChange", NullValueHandling = NullValueHandling.Ignore)]
+ public MeetingChange MeetingChange { get; set; }
+ }
+
+ public class MeetingChange
+ {
+ [JsonProperty("changeType", NullValueHandling = NullValueHandling.Ignore)]
+ public string ChangeType { get; set; }
+
+ [JsonProperty("meeting", NullValueHandling = NullValueHandling.Ignore)]
+ public Meeting Meeting { get; set; }
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/IRunRouteActionMessenger.cs b/3-series/Messengers/IRunRouteActionMessenger.cs
index dbb31b0..88d0a5b 100644
--- a/3-series/Messengers/IRunRouteActionMessenger.cs
+++ b/3-series/Messengers/IRunRouteActionMessenger.cs
@@ -1,7 +1,8 @@
-using System;
-using PepperDash.Essentials.Core;
+using Newtonsoft.Json;
using PepperDash.Core;
+using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
namespace PepperDash.Essentials.AppServer.Messengers
@@ -14,40 +15,36 @@ public class RunRouteActionMessenger : MessengerBase
public IRunRouteAction RoutingDevice { get; private set; }
public RunRouteActionMessenger(string key, IRunRouteAction routingDevice, string messagePath)
- : base(key, messagePath)
+ : base(key, messagePath, routingDevice as Device)
{
- if (routingDevice == null)
- throw new ArgumentNullException("routingDevice");
-
- RoutingDevice = routingDevice;
+ RoutingDevice = routingDevice ?? throw new ArgumentNullException("routingDevice");
- var routingSink = RoutingDevice as IRoutingSink;
- if (routingSink != null)
+ if (RoutingDevice is IRoutingSink routingSink)
{
- routingSink.CurrentSourceChange += routingSink_CurrentSourceChange;
+ routingSink.CurrentSourceChange += RoutingSink_CurrentSourceChange;
}
}
- private void routingSink_CurrentSourceChange(SourceListItem info, ChangeType type)
+ private void RoutingSink_CurrentSourceChange(SourceListItem info, ChangeType type)
{
SendRoutingFullMessageObject();
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendRoutingFullMessageObject));
+ AddAction("/fullStatus", (id, content) => SendRoutingFullMessageObject());
- appServerController.AddAction(MessagePath + "/source",
- new Action(c =>
+ AddAction("/source", (id, content) =>
{
+ var c = content.ToObject();
// assume no sourceListKey
var sourceListKey = string.Empty;
-
+
if (!string.IsNullOrEmpty(c.SourceListKey))
{
// Check for source list in content of message
@@ -55,11 +52,10 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
sourceListKey = c.SourceListKey;
}
- RoutingDevice.RunRouteAction(c.SourceListItem,sourceListKey);
- }));
+ RoutingDevice.RunRouteAction(c.SourceListItemKey, sourceListKey);
+ });
- var sinkDevice = RoutingDevice as IRoutingSink;
- if (sinkDevice != null)
+ if (RoutingDevice is IRoutingSink sinkDevice)
{
sinkDevice.CurrentSourceChange += (o, a) => SendRoutingFullMessageObject();
}
@@ -70,20 +66,24 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
///
private void SendRoutingFullMessageObject()
{
- var sinkDevice = RoutingDevice as IRoutingSink;
-
- if (sinkDevice != null)
+ if (RoutingDevice is IRoutingSink sinkDevice)
{
var sourceKey = sinkDevice.CurrentSourceInfoKey;
if (string.IsNullOrEmpty(sourceKey))
sourceKey = "none";
- PostStatusMessage(new
+ PostStatusMessage(new RoutingStateMessage
{
- selectedSourceKey = sourceKey
+ SelectedSourceKey = sourceKey
});
}
}
}
+
+ public class RoutingStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("selectedSourceKey")]
+ public string SelectedSourceKey { get; set; }
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/LightingBaseMessenger.cs b/3-series/Messengers/LightingBaseMessenger.cs
index 145b9a1..4058c3a 100644
--- a/3-series/Messengers/LightingBaseMessenger.cs
+++ b/3-series/Messengers/LightingBaseMessenger.cs
@@ -1,55 +1,50 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-
+using Newtonsoft.Json;
using PepperDash.Core;
-using PepperDash.Essentials.Core.Lighting;
-
-using Newtonsoft.Json;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Lighting;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class LightingBaseMessenger : MessengerBase
+ public class ILightingScenesMessenger : MessengerBase
{
- protected LightingBase Device { get; private set; }
+ protected ILightingScenes Device { get; private set; }
- public LightingBaseMessenger(string key, LightingBase device, string messagePath)
- : base(key, messagePath, device)
+ public ILightingScenesMessenger(string key, ILightingScenes device, string messagePath)
+ : base(key, messagePath, device as Device)
{
- if (device == null)
- {
- throw new ArgumentNullException("device");
- }
-
- Device = device;
+ Device = device ?? throw new ArgumentNullException("device");
Device.LightingSceneChange += new EventHandler(LightingDevice_LightingSceneChange);
-
+
}
- void LightingDevice_LightingSceneChange(object sender, LightingSceneChangeEventArgs e)
+ private void LightingDevice_LightingSceneChange(object sender, LightingSceneChangeEventArgs e)
{
- var state = new LightingBaseStateMessage();
-
- state.CurrentLightingScene = e.CurrentLightingScene;
+ var state = new LightingBaseStateMessage
+ {
+ CurrentLightingScene = e.CurrentLightingScene
+ };
PostStatusMessage(state);
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
- appServerController.AddAction(string.Format("{0}/fullStatus", MessagePath), new Action(SendFullStatus));
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
- appServerController.AddAction(string.Format("{0}/selectScene", MessagePath), new Action((s) => Device.SelectScene(s)));
+ AddAction("/selectScene", (id, content) =>
+ {
+ var s = content.ToObject();
+ Device.SelectScene(s);
+ });
}
@@ -57,10 +52,11 @@ private void SendFullStatus()
{
Debug.Console(2, "LightingBaseMessenger GetFullStatus");
- var state = new LightingBaseStateMessage();
-
- state.Scenes = Device.LightingScenes;
- state.CurrentLightingScene = Device.CurrentLightingScene;
+ var state = new LightingBaseStateMessage
+ {
+ Scenes = Device.LightingScenes,
+ CurrentLightingScene = Device.CurrentLightingScene
+ };
PostStatusMessage(state);
}
diff --git a/3-series/Messengers/MessengerBase.cs b/3-series/Messengers/MessengerBase.cs
index f1cf26a..75206e3 100644
--- a/3-series/Messengers/MessengerBase.cs
+++ b/3-series/Messengers/MessengerBase.cs
@@ -1,11 +1,12 @@
-using System;
-using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
-
-using Newtonsoft.Json;
-using Newtonsoft.Json.Converters;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -18,15 +19,19 @@ public abstract class MessengerBase : EssentialsDevice, IMobileControlMessenger
public abstract class MessengerBase: EssentialsDevice
#endif
{
- private Device _device;
+ protected IKeyName _device;
+
+ private readonly List _deviceInterfaces;
- private List _deviceIntefaces;
+ private readonly Dictionary> _actions = new Dictionary>();
+
+ public string DeviceKey => _device?.Key ?? "";
///
///
///
#if SERIES4
- public IMobileControl3 AppServerController { get; private set; }
+ public IMobileControl AppServerController { get; private set; }
#else
public MobileControlSystemController AppServerController { get; private set; }
#endif
@@ -49,30 +54,22 @@ protected MessengerBase(string key, string messagePath)
MessagePath = messagePath;
}
- protected MessengerBase(string key, string messagePath, Device device)
+ protected MessengerBase(string key, string messagePath, IKeyName device)
: this(key, messagePath)
{
_device = device;
- _deviceIntefaces = GetInterfaces(_device);
+ _deviceInterfaces = GetInterfaces(_device as Device);
}
///
- /// Gets the intefaces implmented on the device
+ /// Gets the interfaces implmented on the device
///
///
///
private List GetInterfaces(Device device)
{
- var interfaceTypes = device.GetType().GetInterfaces();
-
- List interfaces = new List();
-
- foreach (var i in interfaceTypes)
- {
- interfaces.Add(i.Name);
- }
- return interfaces;
+ return device?.GetType().GetInterfaces().Select((i) => i.Name).ToList() ?? new List();
}
///
@@ -80,81 +77,68 @@ private List GetInterfaces(Device device)
///
///
#if SERIES4
- public void RegisterWithAppServer(IMobileControl3 appServerController)
+ public void RegisterWithAppServer(IMobileControl appServerController)
#else
public void RegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- if (appServerController == null)
- throw new ArgumentNullException("appServerController");
+ AppServerController = appServerController ?? throw new ArgumentNullException("appServerController");
- AppServerController = appServerController;
- CustomRegisterWithAppServer(AppServerController);
+ AppServerController.AddAction(this, HandleMessage);
+
+ RegisterActions();
}
- ///
- /// Implemented in extending classes. Wire up API calls and feedback here
- ///
- ///
-#if SERIES4
- protected virtual void CustomRegisterWithAppServer(IMobileControl3 appServerController)
-#else
- protected virtual void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
-#endif
+ private void HandleMessage(string path, string id, JToken content)
{
- var commMonitor = _device as ICommunicationMonitor;
-
- if (commMonitor != null)
- {
- //Debug.Console(2, this, "Subscribing to CommunicationMonitor.StatusChange on: ", _device.Key);
- commMonitor.CommunicationMonitor.StatusChange += CommunicationMonitor_StatusChange;
+ // replace base path with empty string. Should leave something like /fullStatus
+ var route = path.Replace(MessagePath, string.Empty);
- GetCommunicationMonitorState();
+ if(!_actions.TryGetValue(route, out var action)) {
+ Debug.Console(1, this, $"No action found for path {path}");
+ return;
}
+
+ action(id, content);
}
- private void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
+ protected void AddAction(string path, Action action)
{
- var message = new DeviceStateMessageBase();
- message.CommMonitor = GetCommunicationMonitorState();
+ if (_actions.ContainsKey(path))
+ {
+ //Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Messenger {Key} already has action registered at {path}", this);
+ return;
+ }
+ _actions.Add(path, action);
+ }
- PostStatusMessage(message);
+ public List GetActionPaths()
+ {
+ return _actions.Keys.ToList();
}
- protected CommunicationMonitorState GetCommunicationMonitorState()
+ protected void RemoveAction(string path)
{
- var commMonitor = _device as ICommunicationMonitor;
- if (commMonitor != null)
+ if (!_actions.ContainsKey(path))
{
- var state = new CommunicationMonitorState();
- state.IsOnline = commMonitor.CommunicationMonitor.IsOnline;
- state.Status = commMonitor.CommunicationMonitor.Status;
- //Debug.Console(2, this, "******************GetCommunitcationMonitorState() IsOnline: {0} Status: {1}", state.IsOnline, state.Status);
- return state;
- }
- else
- {
- //Debug.Console(2, this, "******************Device does not implement ICommunicationMonitor");
- return null;
+ return;
}
+
+ _actions.Remove(path);
}
///
- /// Helper for posting status message
+ /// Implemented in extending classes. Wire up API calls and feedback here
///
- /// The contents of the content object
- [Obsolete("Will be removed in next major release, please use overload as substitute")]
- protected void PostStatusMessage(object contentObject)
+ ///
+#if SERIES4
+ protected virtual void RegisterActions()
+#else
+ protected virtual void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
+#endif
{
- if (AppServerController != null)
- {
- AppServerController.SendMessageObject(new
- {
- type = MessagePath,
- content = contentObject
- });
- }
+
}
///
@@ -162,67 +146,74 @@ protected void PostStatusMessage(object contentObject)
///
///
///
- protected void PostStatusMessage(DeviceStateMessageBase message)
+ protected void PostStatusMessage(DeviceStateMessageBase message, string clientId = null)
{
- if (AppServerController != null)
- {
- message.SetInterfaces(_deviceIntefaces);
+ message.SetInterfaces(_deviceInterfaces);
- message.Key = _device.Key;
+ message.Key = _device.Key;
- message.Name = _device.Name;
+ message.Name = _device.Name;
- AppServerController.SendMessageObject(new
- {
- type = MessagePath,
- content = message,
- });
- }
+ PostStatusMessage(JToken.FromObject(message),MessagePath, clientId);
}
-#if SERIES4
- protected void PostStatusMessage(IMobileControlResponseMessage message)
-
+#if SERIES4
+ protected void PostStatusMessage(string type, DeviceStateMessageBase deviceState, string clientId = null)
{
- if (AppServerController == null)
- {
- return;
- }
+ //Debug.Console(2, this, "*********************Setting DeviceStateMessageProperties on MobileControlResponseMessage");
+ deviceState.SetInterfaces(_deviceInterfaces);
- var deviceState = message.Content as DeviceStateMessageBase;
- if (deviceState != null)
- {
- //Debug.Console(2, this, "*********************Setting DeviceStateMessageProperties on MobileControlResponseMessage");
- deviceState.SetInterfaces(_deviceIntefaces);
+ deviceState.Key = _device.Key;
- deviceState.Key = _device.Key;
+ deviceState.Name = _device.Name;
- deviceState.Name = _device.Name;
- }
- //else
- //{
- // Debug.Console(2, this, "*********************Content is not DeviceStateMessageBase");
- //}
+ deviceState.MessageBasePath = MessagePath;
- AppServerController.SendMessageObject(message);
+ PostStatusMessage(JToken.FromObject(deviceState), type, clientId);
}
#endif
+ protected void PostStatusMessage(JToken content, string type = "", string clientId = null)
+ {
+ AppServerController?.SendMessageObject(new MobileControlMessage { Type = !string.IsNullOrEmpty(type) ? type : MessagePath, ClientId = clientId, Content = content });
+ }
protected void PostEventMessage(DeviceEventMessageBase message)
{
- if (AppServerController != null)
+ message.Key = _device.Key;
+
+ message.Name = _device.Name;
+
+ AppServerController?.SendMessageObject(new MobileControlMessage
{
- message.Key = _device.Key;
+ Type = $"/event{MessagePath}/{message.EventType}",
+ Content = JToken.FromObject(message),
+ });
+ }
- message.Name = _device.Name;
+ protected void PostEventMessage(DeviceEventMessageBase message, string eventType)
+ {
+ message.Key = _device.Key;
+
+ message.Name = _device.Name;
- AppServerController.SendMessageObject(new
- {
- type = MessagePath,
- content = message,
- });
- }
+ message.EventType = eventType;
+
+ AppServerController?.SendMessageObject(new MobileControlMessage
+ {
+ Type = $"/event{MessagePath}/{eventType}",
+ Content = JToken.FromObject(message),
+ });
+ }
+
+ protected void PostEventMessage(string eventType)
+ {
+ AppServerController?.SendMessageObject(new MobileControlMessage
+ {
+ Type = $"/event{MessagePath}/{eventType}",
+ Content = JToken.FromObject(new { }),
+ });
}
+
}
public abstract class DeviceMessageBase
@@ -243,26 +234,17 @@ public abstract class DeviceMessageBase
/// The type of the message class
///
[JsonProperty("messageType")]
- public string MessageType
- {
- get
- {
- return this.GetType().Name;
- }
- }
+ public string MessageType => GetType().Name;
+
+ [JsonProperty("messageBasePath")]
+ public string MessageBasePath { get; set; }
}
-
+
///
/// Base class for state messages that includes the type of message and the implmented interfaces
///
public class DeviceStateMessageBase : DeviceMessageBase
{
- ///
- /// For devices that implement ICommunicationMonitor, reports the online status of the device
- ///
- [JsonProperty("commMonitor", NullValueHandling = NullValueHandling.Ignore)]
- public CommunicationMonitorState CommMonitor { get; set; }
-
///
/// The interfaces implmented by the device sending the messsage
///
@@ -287,23 +269,4 @@ public abstract class DeviceEventMessageBase : DeviceMessageBase
public string EventType { get; set; }
}
- ///
- /// Represents the state of the communication monitor
- ///
- public class CommunicationMonitorState
- {
- ///
- /// For devices that implement ICommunicationMonitor, reports the online status of the device
- ///
- [JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
- public bool? IsOnline { get; set; }
-
- ///
- /// For devices that implement ICommunicationMonitor, reports the online status of the device
- ///
- [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
- [JsonConverter(typeof(StringEnumConverter))]
- public MonitorStatus Status { get; set; }
-
- }
}
\ No newline at end of file
diff --git a/3-series/Messengers/RoomEventScheduleMessenger.cs b/3-series/Messengers/RoomEventScheduleMessenger.cs
index c7f3c24..a32eb5a 100644
--- a/3-series/Messengers/RoomEventScheduleMessenger.cs
+++ b/3-series/Messengers/RoomEventScheduleMessenger.cs
@@ -1,20 +1,20 @@
-using System;
-using System.Collections.Generic;
+using Newtonsoft.Json;
using PepperDash.Core;
-using PepperDash.Essentials.Room.Config;
+using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Room.Config;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class RoomEventScheduleMessenger:MessengerBase
+ public class RoomEventScheduleMessenger : MessengerBase
{
- private readonly EssentialsTechRoom _room;
- public RoomEventScheduleMessenger(string key, string messagePath) : base(key, messagePath)
- {
- }
+ private readonly IRoomEventSchedule _room;
- public RoomEventScheduleMessenger(string key, string messagePath, EssentialsTechRoom room)
- : this(key, messagePath)
+
+ public RoomEventScheduleMessenger(string key, string messagePath, IRoomEventSchedule room)
+ : base(key, messagePath, room as Device)
{
_room = room;
}
@@ -22,20 +22,20 @@ public RoomEventScheduleMessenger(string key, string messagePath, EssentialsTech
#region Overrides of MessengerBase
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/save", new Action>(SaveScheduledEvents));
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(() =>
+ AddAction("/saveScheduledEvents", (id, content) => SaveScheduledEvents(content.ToObject>()));
+ AddAction("/status", (id, content) =>
{
var events = _room.GetScheduledEvents();
SendFullStatus(events);
- }));
+ });
- _room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
+ _room.ScheduledEventsChanged += (sender, args) => SendFullStatus(args.ScheduledEvents);
}
#endregion
@@ -60,15 +60,21 @@ private void SaveScheduledEvent(ScheduledEventConfig eventConfig)
}
}
- private void SendFullStatus(List events)
+ private void SendFullStatus(List events)
{
- var message = new
- {
- scheduleEvents = events,
- };
+ var message = new RoomEventScheduleStateMessage
+ {
+ ScheduleEvents = events,
+ };
- PostStatusMessage(message);
+ PostStatusMessage(message);
}
}
+
+ public class RoomEventScheduleStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("scheduleEvents")]
+ public List ScheduleEvents { get; set; }
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/SIMPLAtcMessenger.cs b/3-series/Messengers/SIMPLAtcMessenger.cs
index af85b45..3f2ab69 100644
--- a/3-series/Messengers/SIMPLAtcMessenger.cs
+++ b/3-series/Messengers/SIMPLAtcMessenger.cs
@@ -1,13 +1,14 @@
-using System;
-using System.Collections.Generic;
-using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Devices.Common.Codec;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
-// ReSharper disable once InconsistentNaming
+ // ReSharper disable once InconsistentNaming
public class SIMPLAtcMessenger : MessengerBase
{
private readonly BasicTriList _eisc;
@@ -34,7 +35,7 @@ public SIMPLAtcMessenger(string key, BasicTriList eisc, string messagePath)
JoinMap = new SIMPLAtcJoinMap(201);
- _currentCallItem = new CodecActiveCallItem {Type = eCodecCallType.Audio, Id = "-audio-"};
+ _currentCallItem = new CodecActiveCallItem { Type = eCodecCallType.Audio, Id = "-audio-" };
}
///
@@ -42,13 +43,14 @@ public SIMPLAtcMessenger(string key, BasicTriList eisc, string messagePath)
///
private void SendFullStatus()
{
- PostStatusMessage(new
- {
- calls = GetCurrentCallList(),
- currentCallString = _eisc.GetString(JoinMap.CurrentCallName.JoinNumber),
- currentDialString = _eisc.GetString(JoinMap.CurrentDialString.JoinNumber),
- isInCall = _eisc.GetString(JoinMap.HookState.JoinNumber) == "Connected"
- });
+ PostStatusMessage(JToken.FromObject(new
+ {
+ calls = GetCurrentCallList(),
+ currentCallString = _eisc.GetString(JoinMap.CurrentCallName.JoinNumber),
+ currentDialString = _eisc.GetString(JoinMap.CurrentDialString.JoinNumber),
+ isInCall = _eisc.GetString(JoinMap.HookState.JoinNumber) == "Connected"
+ })
+ );
}
///
@@ -56,7 +58,7 @@ private void SendFullStatus()
///
///
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
@@ -65,7 +67,7 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
_eisc.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
{
- _currentCallItem.Status = (eCodecCallStatus) Enum.Parse(typeof (eCodecCallStatus), s, true);
+ _currentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
//GetCurrentCallList();
SendFullStatus();
});
@@ -84,7 +86,7 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
_eisc.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s =>
{
- _currentCallItem.Direction = (eCodecCallDirection) Enum.Parse(typeof (eCodecCallDirection), s, true);
+ _currentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
SendCallsList();
});
@@ -93,8 +95,8 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
// AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => _eisc.SetBool(u, b)));
// Add straight pulse calls
- Action addAction = (s, u) =>
- AppServerController.AddAction(MessagePath + s, new Action(() => _eisc.PulseBool(u, 100)));
+ void addAction(string s, uint u) =>
+ AddAction(s, (id, content) => _eisc.PulseBool(u, 100));
addAction("/endCallById", JoinMap.EndCall.JoinNumber);
addAction("/endAllCalls", JoinMap.EndCall.JoinNumber);
addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber);
@@ -111,14 +113,20 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
}
// Get status
- AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatus));
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
// Dial on string
- AppServerController.AddAction(MessagePath + "/dial",
- new Action(s => _eisc.SetString(JoinMap.CurrentDialString.JoinNumber, s)));
+ AddAction("/dial",
+ (id, content) =>
+ {
+ var msg = content.ToObject>();
+ _eisc.SetString(JoinMap.CurrentDialString.JoinNumber, msg.Value);
+ });
// Pulse DTMF
- AppServerController.AddAction(MessagePath + "/dtmf", new Action(s =>
+ AddAction("/dtmf", (id, content) =>
{
- var join = JoinMap.Joins[s];
+ var s = content.ToObject>();
+
+ var join = JoinMap.Joins[s.Value];
if (join != null)
{
if (join.JoinNumber > 0)
@@ -126,7 +134,7 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
_eisc.PulseBool(join.JoinNumber, 100);
}
}
- }));
+ });
}
///
@@ -134,10 +142,11 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
///
private void SendCallsList()
{
- PostStatusMessage(new
- {
- calls = GetCurrentCallList(),
- });
+ PostStatusMessage(JToken.FromObject(new
+ {
+ calls = GetCurrentCallList(),
+ })
+ );
}
///
@@ -148,7 +157,7 @@ private List GetCurrentCallList()
{
return _currentCallItem.Status == eCodecCallStatus.Disconnected
? new List()
- : new List {_currentCallItem};
+ : new List { _currentCallItem };
}
}
}
\ No newline at end of file
diff --git a/3-series/Messengers/SIMPLCameraMessenger.cs b/3-series/Messengers/SIMPLCameraMessenger.cs
index 0afb10c..4211146 100644
--- a/3-series/Messengers/SIMPLCameraMessenger.cs
+++ b/3-series/Messengers/SIMPLCameraMessenger.cs
@@ -1,14 +1,15 @@
-using System;
-using System.Collections.Generic;
-using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
-using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
-// ReSharper disable once InconsistentNaming
+ // ReSharper disable once InconsistentNaming
public class SIMPLCameraMessenger : MessengerBase
{
private readonly BasicTriList _eisc;
@@ -32,18 +33,16 @@ public SIMPLCameraMessenger(string key, BasicTriList eisc, string messagePath, u
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- var asc = appServerController;
-
- asc.AddAction(MessagePath + "/fullStatus", new Action(SendCameraFullMessageObject));
+ AddAction("/fullStatus", (id, content) => SendCameraFullMessageObject());
// Add press and holds using helper action
- Action addPhAction = (s, u) =>
- asc.AddAction(MessagePath + s, new PressAndHoldAction(b => _eisc.SetBool(u, b)));
+ void addPhAction(string s, uint u) =>
+ AddAction(s, (id, content) => HandleCameraPressAndHold(content, b => _eisc.SetBool(u, b)));
addPhAction("/cameraUp", _joinMap.TiltUp.JoinNumber);
addPhAction("/cameraDown", _joinMap.TiltDown.JoinNumber);
addPhAction("/cameraLeft", _joinMap.PanLeft.JoinNumber);
@@ -51,8 +50,8 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
addPhAction("/cameraZoomIn", _joinMap.ZoomIn.JoinNumber);
addPhAction("/cameraZoomOut", _joinMap.ZoomOut.JoinNumber);
- Action addAction = (s, u) =>
- asc.AddAction(MessagePath + s, new Action(() => _eisc.PulseBool(u, 100)));
+ void addAction(string s, uint u) =>
+ AddAction(s, (id, content) => _eisc.PulseBool(u, 100));
addAction("/cameraModeAuto", _joinMap.CameraModeAuto.JoinNumber);
addAction("/cameraModeManual", _joinMap.CameraModeManual.JoinNumber);
@@ -70,8 +69,23 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
}
}
+ private void HandleCameraPressAndHold(JToken content, Action cameraAction)
+ {
+ var state = content.ToObject>();
+
+ var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
+ if (timerHandler == null)
+ {
+ return;
+ }
+
+ timerHandler(state.Value, cameraAction);
+
+ cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
+ }
+
#if SERIES4
- public void CustomUnregsiterWithAppServer(IMobileControl3 appServerController)
+ public void CustomUnregsiterWithAppServer(IMobileControl appServerController)
#else
public void CustomUnregsiterWithAppServer(MobileControlSystemController appServerController)
#endif
@@ -118,12 +132,13 @@ private void SendCameraFullMessageObject()
}
}
- PostStatusMessage(new
- {
- cameraMode = GetCameraMode(),
- hasPresets = _eisc.GetBool(_joinMap.SupportsPresets.JoinNumber),
- presets = presetList
- });
+ PostStatusMessage(JToken.FromObject(new
+ {
+ cameraMode = GetCameraMode(),
+ hasPresets = _eisc.GetBool(_joinMap.SupportsPresets.JoinNumber),
+ presets = presetList
+ })
+ );
}
///
@@ -131,10 +146,10 @@ private void SendCameraFullMessageObject()
///
private void PostCameraMode()
{
- PostStatusMessage(new
+ PostStatusMessage(JToken.FromObject(new
{
cameraMode = GetCameraMode()
- });
+ }));
}
///
diff --git a/3-series/Messengers/SIMPLDirectRouteMessenger.cs b/3-series/Messengers/SIMPLDirectRouteMessenger.cs
index 68584a2..46899cd 100644
--- a/3-series/Messengers/SIMPLDirectRouteMessenger.cs
+++ b/3-series/Messengers/SIMPLDirectRouteMessenger.cs
@@ -1,13 +1,13 @@
-using System;
-using System.Collections.Generic;
-using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class SimplDirectRouteMessenger:MessengerBase
+ public class SimplDirectRouteMessenger : MessengerBase
{
private readonly BasicTriList _eisc;
@@ -27,32 +27,30 @@ public SimplDirectRouteMessenger(string key, BasicTriList eisc, string messagePa
#region Overrides of MessengerBase
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 controller)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController controller)
#endif
{
Debug.Console(2, "********** Direct Route Messenger CustomRegisterWithAppServer **********");
-
+
//Audio source
_eisc.SetStringSigAction(JoinMap.SourceForDestinationAudio.JoinNumber,
- s => controller.SendMessageObject(new
+ s => PostStatusMessage(JToken.FromObject(new
{
- type = MessagePath + "/programAudio/currentSource",
- content = new
- {
- selectedSourceKey = s,
- }
- }));
-
- controller.AddAction(MessagePath + "/programAudio/selectSource",
- new Action(
- s => _eisc.StringInput[JoinMap.SourceForDestinationAudio.JoinNumber].StringValue = s));
+ selectedSourceKey = s,
+ })
+ ));
+ AddAction("/programAudio/selectSource", (id, content) =>
+ {
+ var msg = content.ToObject>();
+ _eisc.StringInput[JoinMap.SourceForDestinationAudio.JoinNumber].StringValue = msg.Value;
+ });
- controller.AddAction(MessagePath + "/fullStatus", new Action(() =>
+ AddAction("/fullStatus", (id, content) =>
{
foreach (var dest in DestinationList)
{
@@ -65,45 +63,38 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
UpdateSourceForDestination(source, key);
}
- controller.SendMessageObject(new
+ PostStatusMessage(JToken.FromObject(new
{
- type = MessagePath + "/programAudio/currentSource",
- content = new
- {
- selectedSourceKey = _eisc.StringOutput[JoinMap.SourceForDestinationAudio.JoinNumber].StringValue
- }
- });
+ selectedSourceKey = _eisc.StringOutput[JoinMap.SourceForDestinationAudio.JoinNumber].StringValue
+ })
+ );
- controller.SendMessageObject(new
+ PostStatusMessage(JToken.FromObject(new
{
- type = MessagePath + "/advancedSharingMode",
- content = new
- {
- advancedSharingActive = _eisc.BooleanOutput[JoinMap.AdvancedSharingModeFb.JoinNumber].BoolValue
- }
- });
- }));
+ advancedSharingActive = _eisc.BooleanOutput[JoinMap.AdvancedSharingModeFb.JoinNumber].BoolValue
+ })
+ );
+ });
- controller.AddAction(MessagePath + "/advancedSharingMode",new Action((b) =>
+ AddAction("/advancedSharingMode", (id, content) =>
{
- Debug.Console(1, "Current Sharing Mode: {2}\r\nadvanced sharing mode: {0} join number: {1}", b,
+ var b = content.ToObject>();
+
+ Debug.Console(1, "Current Sharing Mode: {2}\r\nadvanced sharing mode: {0} join number: {1}", b.Value,
JoinMap.AdvancedSharingModeOn.JoinNumber,
_eisc.BooleanOutput[JoinMap.AdvancedSharingModeOn.JoinNumber].BoolValue);
-
- _eisc.SetBool(JoinMap.AdvancedSharingModeOn.JoinNumber, b);
- _eisc.SetBool(JoinMap.AdvancedSharingModeOff.JoinNumber, !b);
+
+ _eisc.SetBool(JoinMap.AdvancedSharingModeOn.JoinNumber, b.Value);
+ _eisc.SetBool(JoinMap.AdvancedSharingModeOff.JoinNumber, !b.Value);
_eisc.PulseBool(JoinMap.AdvancedSharingModeToggle.JoinNumber);
- }));
+ });
_eisc.SetBoolSigAction(JoinMap.AdvancedSharingModeFb.JoinNumber,
- (b) => controller.SendMessageObject(new
+ (b) => PostStatusMessage(JToken.FromObject(new
{
- type = MessagePath + "/advancedSharingMode",
- content = new
- {
- advancedSharingActive = b
- }
- }));
+ advancedSharingActive = b
+ })
+ ));
}
public void RegisterForDestinationPaths()
@@ -117,10 +108,12 @@ public void RegisterForDestinationPaths()
_eisc.SetStringSigAction((uint)(JoinMap.SourceForDestinationJoinStart.JoinNumber + dest.Order),
s => UpdateSourceForDestination(s, key));
- AppServerController.AddAction(String.Format("{0}/{1}/selectSource", MessagePath, key),
- new Action(
- s =>
- _eisc.StringInput[(uint)(JoinMap.SourceForDestinationJoinStart.JoinNumber + dest.Order)].StringValue = s));
+ AddAction($"/{key}/selectSource", (id, content) =>
+ {
+ var s = content.ToObject>();
+
+ _eisc.StringInput[(uint)(JoinMap.SourceForDestinationJoinStart.JoinNumber + dest.Order)].StringValue = s.Value;
+ });
}
}
@@ -128,14 +121,10 @@ public void RegisterForDestinationPaths()
private void UpdateSourceForDestination(string sourceKey, string destKey)
{
- AppServerController.SendMessageObject(new
+ PostStatusMessage(JToken.FromObject(new
{
- type = String.Format("{0}/{1}/currentSource", MessagePath, destKey),
- content = new
- {
- selectedSourceKey = sourceKey
- }
- });
+ selectedSourceKey = sourceKey
+ }), $"{MessagePath}/{destKey}/currentSource");
}
}
diff --git a/3-series/Messengers/SIMPLRouteMessenger.cs b/3-series/Messengers/SIMPLRouteMessenger.cs
index eab8fc2..ccdbb27 100644
--- a/3-series/Messengers/SIMPLRouteMessenger.cs
+++ b/3-series/Messengers/SIMPLRouteMessenger.cs
@@ -1,5 +1,5 @@
-using System;
-using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
@@ -31,21 +31,24 @@ public SIMPLRouteMessenger(string key, BasicTriList eisc, string messagePath, ui
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- appServerController.AddAction(MessagePath + "/fullStatus",
- new Action(() => SendRoutingFullMessageObject(_eisc.GetString(_joinStart + StringJoin.CurrentSource))));
+ AddAction("/fullStatus",
+ (id, content) => SendRoutingFullMessageObject(_eisc.GetString(_joinStart + StringJoin.CurrentSource)));
- appServerController.AddAction(MessagePath + "/source",
- new Action(
- c => _eisc.SetString(_joinStart + StringJoin.CurrentSource, c.SourceListItem)));
+ AddAction("/source", (id, content) =>
+ {
+ var c = content.ToObject();
+
+ _eisc.SetString(_joinStart + StringJoin.CurrentSource, c.SourceListItemKey);
+ });
}
#if SERIES4
- public void CustomUnregsiterWithAppServer(IMobileControl3 appServerController)
+ public void CustomUnregsiterWithAppServer(IMobileControl appServerController)
#else
public void CustomUnregsiterWithAppServer(MobileControlSystemController appServerController)
#endif
@@ -64,10 +67,11 @@ private void SendRoutingFullMessageObject(string sourceKey)
if (string.IsNullOrEmpty(sourceKey))
sourceKey = "none";
- PostStatusMessage(new
- {
- selectedSourceKey = sourceKey
- });
+ PostStatusMessage(JToken.FromObject(new
+ {
+ selectedSourceKey = sourceKey
+ })
+ );
}
}
}
\ No newline at end of file
diff --git a/3-series/Messengers/SIMPLVtcMessenger.cs b/3-series/Messengers/SIMPLVtcMessenger.cs
index 2f5bd99..a421e06 100644
--- a/3-series/Messengers/SIMPLVtcMessenger.cs
+++ b/3-series/Messengers/SIMPLVtcMessenger.cs
@@ -1,15 +1,16 @@
-using System;
-using System.Collections.Generic;
-using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Devices.Common.Codec;
-using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using PepperDash.Essentials.Devices.Common.Codec;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.AppServer.Messengers
{
-// ReSharper disable once InconsistentNaming
+ // ReSharper disable once InconsistentNaming
public class SIMPLVtcMessenger : MessengerBase
{
private readonly BasicTriList _eisc;
@@ -35,7 +36,7 @@ public SIMPLVtcMessenger(string key, BasicTriList eisc, string messagePath)
JoinMap = new SIMPLVtcJoinMap(1001);
- _currentCallItem = new CodecActiveCallItem {Type = eCodecCallType.Video, Id = "-video-"};
+ _currentCallItem = new CodecActiveCallItem { Type = eCodecCallType.Video, Id = "-video-" };
}
///
@@ -43,15 +44,14 @@ public SIMPLVtcMessenger(string key, BasicTriList eisc, string messagePath)
///
///
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
- {
- var asc = appServerController;
+ {
_eisc.SetStringSigAction(JoinMap.HookState.JoinNumber, s =>
{
- _currentCallItem.Status = (eCodecCallStatus) Enum.Parse(typeof (eCodecCallStatus), s, true);
+ _currentCallItem.Status = (eCodecCallStatus)Enum.Parse(typeof(eCodecCallStatus), s, true);
PostFullStatus(); // SendCallsList();
});
@@ -69,7 +69,7 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
_eisc.SetStringSigAction(JoinMap.CallDirection.JoinNumber, s =>
{
- _currentCallItem.Direction = (eCodecCallDirection) Enum.Parse(typeof (eCodecCallDirection), s, true);
+ _currentCallItem.Direction = (eCodecCallDirection)Enum.Parse(typeof(eCodecCallDirection), s, true);
PostCallsList();
});
@@ -95,13 +95,13 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
PostCallsList();
});
- _eisc.SetStringSigAction(JoinMap.IncomingCallName.JoinNumber, s =>
+ _eisc.SetStringSigAction(JoinMap.IncomingCallName.JoinNumber, s =>
{
- if(_incomingCallItem != null)
+ if (_incomingCallItem != null)
{
_incomingCallItem.Name = s;
PostCallsList();
- }
+ }
});
_eisc.SetStringSigAction(JoinMap.IncomingCallNumber.JoinNumber, s =>
@@ -113,14 +113,14 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
}
});
- _eisc.SetBoolSigAction(JoinMap.CameraSupportsAutoMode.JoinNumber, b => PostStatusMessage(new
+ _eisc.SetBoolSigAction(JoinMap.CameraSupportsAutoMode.JoinNumber, b => PostStatusMessage(JToken.FromObject(new
{
cameraSupportsAutoMode = b
- }));
- _eisc.SetBoolSigAction(JoinMap.CameraSupportsOffMode.JoinNumber, b => PostStatusMessage(new
+ })));
+ _eisc.SetBoolSigAction(JoinMap.CameraSupportsOffMode.JoinNumber, b => PostStatusMessage(JToken.FromObject(new
{
cameraSupportsOffMode = b
- }));
+ })));
// Directory insanity
_eisc.SetUShortSigAction(JoinMap.DirectoryRowCount.JoinNumber, u =>
@@ -136,42 +136,42 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
_previousDirectoryLength = u;
});
- _eisc.SetStringSigAction(JoinMap.DirectoryEntrySelectedName.JoinNumber, s => PostStatusMessage(new
+ _eisc.SetStringSigAction(JoinMap.DirectoryEntrySelectedName.JoinNumber, s => PostStatusMessage(JToken.FromObject(new
{
directoryContactSelected = new
{
name = _eisc.GetString(JoinMap.DirectoryEntrySelectedName.JoinNumber),
}
- }));
+ })));
- _eisc.SetStringSigAction(JoinMap.DirectoryEntrySelectedNumber.JoinNumber, s => PostStatusMessage(new
+ _eisc.SetStringSigAction(JoinMap.DirectoryEntrySelectedNumber.JoinNumber, s => PostStatusMessage(JToken.FromObject(new
{
directoryContactSelected = new
{
number = _eisc.GetString(JoinMap.DirectoryEntrySelectedNumber.JoinNumber),
}
- }));
+ })));
- _eisc.SetStringSigAction(JoinMap.DirectorySelectedFolderName.JoinNumber, s => PostStatusMessage(new
+ _eisc.SetStringSigAction(JoinMap.DirectorySelectedFolderName.JoinNumber, s => PostStatusMessage(JToken.FromObject(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
+ _eisc.SetBoolSigAction(JoinMap.CameraSelfView.JoinNumber, b => PostStatusMessage(JToken.FromObject(new
{
cameraSelfView = b
- }));
+ })));
_eisc.SetUShortSigAction(JoinMap.CameraNumberSelect.JoinNumber, u => PostSelectedCamera());
// Add press and holds using helper action
- Action addPhAction = (s, u) =>
- AppServerController.AddAction(MessagePath + s, new PressAndHoldAction(b => _eisc.SetBool(u, b)));
+ void addPhAction(string s, uint u) =>
+ AddAction(s, (id, content) => HandleCameraPressAndHold(content, b => _eisc.SetBool(u, b)));
addPhAction("/cameraUp", JoinMap.CameraTiltUp.JoinNumber);
addPhAction("/cameraDown", JoinMap.CameraTiltDown.JoinNumber);
addPhAction("/cameraLeft", JoinMap.CameraPanLeft.JoinNumber);
@@ -180,8 +180,8 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
addPhAction("/cameraZoomOut", JoinMap.CameraZoomOut.JoinNumber);
// Add straight pulse calls using helper action
- Action addAction = (s, u) =>
- AppServerController.AddAction(MessagePath + s, new Action(() => _eisc.PulseBool(u, 100)));
+ void addAction(string s, uint u) =>
+ AddAction(s, (id, content) => _eisc.PulseBool(u, 100));
addAction("/endCallById", JoinMap.EndCall.JoinNumber);
addAction("/endAllCalls", JoinMap.EndCall.JoinNumber);
addAction("/acceptById", JoinMap.IncomingAnswer.JoinNumber);
@@ -203,7 +203,11 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
addAction("/cameraSelfView", JoinMap.CameraSelfView.JoinNumber);
addAction("/cameraLayout", JoinMap.CameraLayout.JoinNumber);
- asc.AddAction("/cameraSelect", new Action(SelectCamera));
+ AddAction("/cameraSelect", (id, content) =>
+ {
+ var s = content.ToObject>();
+ SelectCamera(s.Value);
+ });
// camera presets
for (uint i = 0; i < 6; i++)
@@ -211,16 +215,21 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
addAction("/cameraPreset" + (i + 1), JoinMap.CameraPresetStart.JoinNumber + i);
}
- asc.AddAction(MessagePath + "/isReady", new Action(PostIsReady));
+ AddAction("/isReady", (id, content) => PostIsReady());
// Get status
- asc.AddAction(MessagePath + "/fullStatus", new Action(PostFullStatus));
+ AddAction("/fullStatus", (id, content) => PostFullStatus());
// Dial on string
- asc.AddAction(MessagePath + "/dial", new Action(s =>
- _eisc.SetString(JoinMap.CurrentDialString.JoinNumber, s)));
+ AddAction("/dial", (id, content) =>
+ {
+ var s = content.ToObject>();
+
+ _eisc.SetString(JoinMap.CurrentDialString.JoinNumber, s.Value);
+ });
// Pulse DTMF
- AppServerController.AddAction(MessagePath + "/dtmf", new Action(s =>
+ AddAction("/dtmf", (id, content) =>
{
- var join = JoinMap.Joins[s];
+ var s = content.ToObject>();
+ var join = JoinMap.Joins[s.Value];
if (join != null)
{
if (join.JoinNumber > 0)
@@ -228,19 +237,20 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
_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(s =>
+ AddAction("/directoryRoot",
+ (id, content) => _eisc.PulseBool(JoinMap.DirectoryRoot.JoinNumber));
+ AddAction("/directoryBack",
+ (id, content) => _eisc.PulseBool(JoinMap.DirectoryFolderBack.JoinNumber));
+ AddAction("/directoryById", (id, content) =>
{
+ var s = content.ToObject>();
// the id should contain the line number to forward to simpl
try
{
- var u = ushort.Parse(s);
+ var u = ushort.Parse(s.Value);
_eisc.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u);
_eisc.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber);
}
@@ -249,12 +259,13 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
Debug.Console(1, this, Debug.ErrorLogLevel.Warning,
"/directoryById request contains non-numeric ID incompatible with SIMPL bridge");
}
- }));
- asc.AddAction(MessagePath + "/directorySelectContact", new Action(s =>
+ });
+ AddAction("/directorySelectContact", (id, content) =>
{
+ var s = content.ToObject>();
try
{
- var u = ushort.Parse(s);
+ var u = ushort.Parse(s.Value);
_eisc.SetUshort(JoinMap.DirectorySelectRow.JoinNumber, u);
_eisc.PulseBool(JoinMap.DirectoryLineSelected.JoinNumber);
}
@@ -262,10 +273,10 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
{
Debug.Console(2, this, "Error parsing contact from {0} for path /directorySelectContact", s);
}
- }));
- asc.AddAction(MessagePath + "/directoryDialContact",
- new Action(() => _eisc.PulseBool(JoinMap.DirectoryDialSelectedLine.JoinNumber)));
- asc.AddAction(MessagePath + "/getDirectory", new Action(() =>
+ });
+ AddAction("/directoryDialContact",
+ (id, content) => _eisc.PulseBool(JoinMap.DirectoryDialSelectedLine.JoinNumber));
+ AddAction("/getDirectory", (id, content) =>
{
if (_eisc.GetUshort(JoinMap.DirectoryRowCount.JoinNumber) > 0)
{
@@ -275,15 +286,31 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
{
_eisc.PulseBool(JoinMap.DirectoryRoot.JoinNumber);
}
- }));
+ });
+ }
+
+ private void HandleCameraPressAndHold(JToken content, Action cameraAction)
+ {
+ var state = content.ToObject>();
+
+ var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
+ if (timerHandler == null)
+ {
+ return;
+ }
+
+ timerHandler(state.Value, cameraAction);
+
+ cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
}
///
///
///
+ ///
private void PostFullStatus()
{
- PostStatusMessage(new
+ PostStatusMessage(JToken.FromObject(new
{
calls = GetCurrentCallList(),
cameraMode = GetCameraMode(),
@@ -305,7 +332,7 @@ private void PostFullStatus()
hasCameras = true,
showCamerasWhenNotInCall = _eisc.BooleanOutput[503].BoolValue,
selectedCamera = GetSelectedCamera(),
- });
+ }));
}
///
@@ -346,7 +373,7 @@ private void PostDirectory()
directoryResults = items
}
};
- PostStatusMessage(directoryMessage);
+ PostStatusMessage(JToken.FromObject(directoryMessage));
}
///
@@ -354,10 +381,10 @@ private void PostDirectory()
///
private void PostCameraMode()
{
- PostStatusMessage(new
+ PostStatusMessage(JToken.FromObject(new
{
cameraMode = GetCameraMode()
- });
+ }));
}
///
@@ -375,10 +402,10 @@ private string GetCameraMode()
private void PostSelectedCamera()
{
- PostStatusMessage(new
+ PostStatusMessage(JToken.FromObject(new
{
selectedCamera = GetSelectedCamera()
- });
+ }));
}
///
@@ -404,10 +431,10 @@ private string GetSelectedCamera()
///
private void PostIsReady()
{
- PostStatusMessage(new
+ PostStatusMessage(JToken.FromObject(new
{
isReady = true
- });
+ }));
}
///
@@ -415,10 +442,10 @@ private void PostIsReady()
///
private void PostCallsList()
{
- PostStatusMessage(new
+ PostStatusMessage(JToken.FromObject(new
{
calls = GetCurrentCallList(),
- });
+ }));
}
///
@@ -429,7 +456,7 @@ private void SelectCamera(string s)
{
var cam = s.Substring(6);
_eisc.SetUshort(JoinMap.CameraNumberSelect.JoinNumber,
- (ushort) (cam.ToLower() == "far" ? 100 : UInt16.Parse(cam)));
+ (ushort)(cam.ToLower() == "far" ? 100 : ushort.Parse(cam)));
}
///
diff --git a/3-series/Messengers/ShadeBaseMessenger.cs b/3-series/Messengers/ShadeBaseMessenger.cs
index fb4ecc7..e004153 100644
--- a/3-series/Messengers/ShadeBaseMessenger.cs
+++ b/3-series/Messengers/ShadeBaseMessenger.cs
@@ -1,87 +1,77 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-
+using Newtonsoft.Json;
using PepperDash.Core;
-using PepperDash.Essentials.Core.Shades;
-
-using Newtonsoft.Json;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Shades;
+using System;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class ShadeBaseMessenger : MessengerBase
+ public class IShadesOpenCloseStopMessenger : MessengerBase
{
- protected ShadeBase Device { get; private set; }
+ private readonly IShadesOpenCloseStop device;
- public ShadeBaseMessenger(string key, ShadeBase device, string messagePath)
- : base(key, messagePath, device)
+ public IShadesOpenCloseStopMessenger(string key, IShadesOpenCloseStop shades, string messagePath)
+ : base(key, messagePath, shades as Device)
{
- if (device == null)
- {
- throw new ArgumentNullException("device");
- }
-
- Device = device;
+ device = shades;
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
- appServerController.AddAction(string.Format("{0}/fullStatus", MessagePath), new Action(SendFullStatus));
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
- appServerController.AddAction(string.Format("{0}/shadeUp", MessagePath), new Action( () =>
+ AddAction("/shadeUp", (id, content) =>
{
- Device.Open();
+ device.Open();
- }));
+ });
- appServerController.AddAction(string.Format("{0}/shadeDown", MessagePath), new Action(() =>
+ AddAction("/shadeDown", (id, content) =>
{
- Device.Close();
+ device.Close();
- }));
+ });
- var stopDevice = Device as IShadesOpenCloseStop;
+ var stopDevice = device;
if (stopDevice != null)
{
- appServerController.AddAction(string.Format("{0}/stopOrPreset", MessagePath), new Action(() =>
+ AddAction("/stopOrPreset", (id, content) =>
{
stopDevice.Stop();
- }));
+ });
}
- var feedbackDevice = Device as IShadesOpenClosedFeedback;
- if (feedbackDevice != null)
+ if (device is IShadesOpenClosedFeedback feedbackDevice)
{
- feedbackDevice.ShadeIsOpenFeedback.OutputChange += new EventHandler(ShadeIsOpenFeedback_OutputChange);
- feedbackDevice.ShadeIsClosedFeedback.OutputChange += new EventHandler(ShadeIsClosedFeedback_OutputChange);
+ feedbackDevice.ShadeIsOpenFeedback.OutputChange += new EventHandler(ShadeIsOpenFeedback_OutputChange);
+ feedbackDevice.ShadeIsClosedFeedback.OutputChange += new EventHandler(ShadeIsClosedFeedback_OutputChange);
}
}
- void ShadeIsOpenFeedback_OutputChange(object sender, PepperDash.Essentials.Core.FeedbackEventArgs e)
+ private void ShadeIsOpenFeedback_OutputChange(object sender, Core.FeedbackEventArgs e)
{
- var state = new ShadeBaseStateMessage();
-
- state.IsOpen = e.BoolValue;
+ var state = new ShadeBaseStateMessage
+ {
+ IsOpen = e.BoolValue
+ };
PostStatusMessage(state);
}
- void ShadeIsClosedFeedback_OutputChange(object sender, PepperDash.Essentials.Core.FeedbackEventArgs e)
+ private void ShadeIsClosedFeedback_OutputChange(object sender, Core.FeedbackEventArgs e)
{
- var state = new ShadeBaseStateMessage();
-
- state.IsClosed = e.BoolValue;
+ var state = new ShadeBaseStateMessage
+ {
+ IsClosed = e.BoolValue
+ };
PostStatusMessage(state);
}
@@ -91,8 +81,7 @@ private void SendFullStatus()
{
var state = new ShadeBaseStateMessage();
- var feedbackDevice = Device as IShadesOpenClosedFeedback;
- if (feedbackDevice != null)
+ if (device is IShadesOpenClosedFeedback feedbackDevice)
{
state.IsOpen = feedbackDevice.ShadeIsOpenFeedback.BoolValue;
state.IsClosed = feedbackDevice.ShadeIsClosedFeedback.BoolValue;
diff --git a/3-series/Messengers/SystemMonitorMessenger.cs b/3-series/Messengers/SystemMonitorMessenger.cs
index 05ced47..92ffd63 100644
--- a/3-series/Messengers/SystemMonitorMessenger.cs
+++ b/3-series/Messengers/SystemMonitorMessenger.cs
@@ -1,26 +1,26 @@
-using System;
-using Crestron.SimplSharp;
+using Crestron.SimplSharp;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using PepperDash.Core;
-using PepperDash.Essentials.Core.Monitoring;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Monitoring;
+using System;
+using System.Threading.Tasks;
namespace PepperDash.Essentials.AppServer.Messengers
{
public class SystemMonitorMessenger : MessengerBase
{
- public SystemMonitorController SysMon { get; private set; }
+ private readonly SystemMonitorController systemMonitor;
public SystemMonitorMessenger(string key, SystemMonitorController sysMon, string messagePath)
- : base(key, messagePath)
+ : base(key, messagePath, sysMon)
{
- if (sysMon == null)
- throw new ArgumentNullException("sysMon");
+ systemMonitor = sysMon ?? throw new ArgumentNullException("sysMon");
- SysMon = sysMon;
+ systemMonitor.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged;
- SysMon.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged;
-
- foreach (var p in SysMon.ProgramStatusFeedbackCollection)
+ foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
{
p.Value.ProgramInfoChanged += ProgramInfoChanged;
}
@@ -39,7 +39,8 @@ private void ProgramInfoChanged(object sender, ProgramInfoEventArgs e)
if (e.ProgramInfo != null)
{
//Debug.Console(1, "Posting Status Message: {0}", e.ProgramInfo.ToString());
- PostStatusMessage(e.ProgramInfo);
+ PostStatusMessage(JToken.FromObject(e.ProgramInfo)
+ );
}
}
@@ -57,9 +58,10 @@ private void SendFullStatusMessage()
{
SendSystemMonitorStatusMessage();
- foreach (var p in SysMon.ProgramStatusFeedbackCollection)
+ foreach (var p in systemMonitor.ProgramStatusFeedbackCollection)
{
- PostStatusMessage(p.Value.ProgramInfo);
+ PostStatusMessage(JToken.FromObject(p.Value.ProgramInfo)
+ );
}
}
@@ -68,24 +70,47 @@ private 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
- }));
+ Task.Run(() => PostStatusMessage(JToken.FromObject(new SystemMonitorStateMessage
+ {
+
+ TimeZone = systemMonitor.TimeZoneFeedback.IntValue,
+ TimeZoneName = systemMonitor.TimeZoneTextFeedback.StringValue,
+ IoControllerVersion = systemMonitor.IoControllerVersionFeedback.StringValue,
+ SnmpVersion = systemMonitor.SnmpVersionFeedback.StringValue,
+ BacnetVersion = systemMonitor.BaCnetAppVersionFeedback.StringValue,
+ ControllerVersion = systemMonitor.ControllerVersionFeedback.StringValue
+ })
+ ));
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- AppServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatusMessage));
+ AddAction("/fullStatus", (id, content) => SendFullStatusMessage());
}
}
+
+ public class SystemMonitorStateMessage
+ {
+ [JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
+ public int TimeZone { get; set; }
+
+ [JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
+ public string TimeZoneName { get; set; }
+
+ [JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
+ public string IoControllerVersion { get; set; }
+
+ [JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
+ public string SnmpVersion { get; set; }
+
+ [JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
+ public string BacnetVersion { get; set; }
+
+ [JsonProperty("timeZone", NullValueHandling = NullValueHandling.Ignore)]
+ public string ControllerVersion { get; set; }
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/TwoWayDisplayBaseMessenger.cs b/3-series/Messengers/TwoWayDisplayBaseMessenger.cs
index cc95fc7..baf970d 100644
--- a/3-series/Messengers/TwoWayDisplayBaseMessenger.cs
+++ b/3-series/Messengers/TwoWayDisplayBaseMessenger.cs
@@ -1,14 +1,13 @@
-using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using TwoWayDisplayBase = PepperDash.Essentials.Devices.Common.Displays.TwoWayDisplayBase;
namespace PepperDash.Essentials.AppServer.Messengers
{
- public class TwoWayDisplayBaseMessenger:MessengerBase
+ public class TwoWayDisplayBaseMessenger : MessengerBase
{
- private const string PowerStatusPath = "/powerStatus";
- private const string InputStatusPath = "/inputStatus";
-
private readonly TwoWayDisplayBase _display;
public TwoWayDisplayBaseMessenger(string key, string messagePath) : base(key, messagePath)
@@ -25,26 +24,26 @@ public TwoWayDisplayBaseMessenger(string key, string messagePath, TwoWayDisplayB
public void SendFullStatus()
{
- var messageObj = new
+ var messageObj = new TwoWayDisplayBaseStateMessage
{
- powerState = _display.PowerIsOnFeedback.BoolValue,
- currentInput = _display.CurrentInputFeedback.StringValue
+ //PowerState = _display.PowerIsOnFeedback.BoolValue,
+ CurrentInput = _display.CurrentInputFeedback.StringValue
};
PostStatusMessage(messageObj);
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
- appServerController.AddAction(MessagePath + "/fullStatus", new Action(SendFullStatus));
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
- _display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
+ //_display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
_display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange;
_display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange;
_display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange;
@@ -52,61 +51,52 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
private void CurrentInputFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
- var messageObj = new
- {
- type = MessagePath,
- content = new
+ PostStatusMessage(JToken.FromObject(new
{
currentInput = feedbackEventArgs.StringValue
- }
- };
-
- AppServerController.SendMessageObject(messageObj);
+ })
+ );
}
- private void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
- {
- var messageObj = new
- {
- type = MessagePath,
- content = new
- {
- powerState = feedbackEventArgs.BoolValue
- }
- };
-
- AppServerController.SendMessageObject(messageObj);
- }
+ //private void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
+ //{
+ // PostStatusMessage(JToken.FromObject(new
+ // {
+ // powerState = feedbackEventArgs.BoolValue
+ // })
+ // );
+ //}
private void IsWarmingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
- var messageObj = new
- {
- type = MessagePath,
- content = new
+ PostStatusMessage(JToken.FromObject(new
{
isWarming = feedbackEventArgs.BoolValue
- }
- };
-
- AppServerController.SendMessageObject(messageObj);
+ })
+ );
}
private void IsCoolingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
- var messageObj = new
- {
- type = MessagePath,
- content = new
+ PostStatusMessage(JToken.FromObject(new
{
isCooling = feedbackEventArgs.BoolValue
- }
- };
+ })
+ );
- AppServerController.SendMessageObject(messageObj);
+
}
#endregion
}
+
+ public class TwoWayDisplayBaseStateMessage : DeviceStateMessageBase
+ {
+ //[JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
+ //public bool? PowerState { get; set; }
+
+ [JsonProperty("currentInput", NullValueHandling = NullValueHandling.Ignore)]
+ public string CurrentInput { get; set; }
+ }
}
\ No newline at end of file
diff --git a/3-series/Messengers/VideoCodecBaseMessenger.cs b/3-series/Messengers/VideoCodecBaseMessenger.cs
index 2bc8aa7..fecbc68 100644
--- a/3-series/Messengers/VideoCodecBaseMessenger.cs
+++ b/3-series/Messengers/VideoCodecBaseMessenger.cs
@@ -1,16 +1,17 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using Crestron.SimplSharp;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.Cameras;
+using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
-using Crestron.SimplSharp;
-using PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom;
-using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using static PepperDash.Essentials.AppServer.Messengers.VideoCodecBaseStateMessage.CameraStatus;
namespace PepperDash.Essentials.AppServer.Messengers
{
@@ -35,27 +36,21 @@ public class VideoCodecBaseMessenger : MessengerBase
public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messagePath)
: base(key, messagePath, codec)
{
- if (codec == null)
- throw new ArgumentNullException("codec");
+ Codec = codec ?? throw new ArgumentNullException("codec");
+ codec.CallStatusChange += Codec_CallStatusChange;
+ codec.IsReadyChange += Codec_IsReadyChange;
- Codec = codec;
- codec.CallStatusChange += codec_CallStatusChange;
- codec.IsReadyChange += codec_IsReadyChange;
-
- var dirCodec = codec as IHasDirectory;
- if (dirCodec != null)
+ if (codec is IHasDirectory dirCodec)
{
- dirCodec.DirectoryResultReturned += dirCodec_DirectoryResultReturned;
+ dirCodec.DirectoryResultReturned += DirCodec_DirectoryResultReturned;
}
- var recCodec = codec as IHasCallHistory;
- if (recCodec != null)
+ if (codec is IHasCallHistory recCodec)
{
recCodec.CallHistory.RecentCallsListHasChanged += CallHistory_RecentCallsListHasChanged;
}
- var pwPromptCodec = codec as IPasswordPrompt;
- if (pwPromptCodec != null)
+ if (codec is IPasswordPrompt pwPromptCodec)
{
pwPromptCodec.PasswordRequired += OnPasswordRequired;
}
@@ -63,16 +58,15 @@ public VideoCodecBaseMessenger(string key, VideoCodecBase codec, string messageP
private void OnPasswordRequired(object sender, PasswordPromptEventArgs args)
{
- var eventMsg = new PasswordPromptEventMessage()
+ var eventMsg = new PasswordPromptEventMessage
{
Message = args.Message,
LastAttemptWasIncorrect = args.LastAttemptWasIncorrect,
LoginAttemptFailed = args.LoginAttemptFailed,
LoginAttemptCancelled = args.LoginAttemptCancelled,
+ EventType = "passwordPrompt"
};
- eventMsg.EventType = "passwordPrompt";
-
PostEventMessage(eventMsg);
}
@@ -85,8 +79,7 @@ private void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
{
var state = new VideoCodecBaseStateMessage();
- var codecCallHistory = sender as CodecCallHistory;
- if (codecCallHistory == null) return;
+ if (!(sender is CodecCallHistory codecCallHistory)) return;
var recents = codecCallHistory.RecentCalls;
if (recents != null)
@@ -102,10 +95,9 @@ private void CallHistory_RecentCallsListHasChanged(object sender, EventArgs e)
///
///
///
- protected virtual void dirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
+ protected virtual void DirCodec_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{
- var hasDirectory = Codec as IHasDirectory;
- if (hasDirectory != null)
+ if (Codec is IHasDirectory)
SendDirectory(e.Directory);
}
@@ -116,9 +108,8 @@ protected void SendDirectory(CodecDirectory directory)
{
var state = new VideoCodecBaseStateMessage();
- var dirCodec = Codec as IHasDirectory;
- if (dirCodec != null)
+ if (Codec is IHasDirectory dirCodec)
{
Debug.Console(2, this, "Sending Directory. Directory Item Count: {0}", directory.CurrentDirectoryResults.Count);
@@ -126,62 +117,18 @@ protected void SendDirectory(CodecDirectory directory)
state.CurrentDirectory = directory;
CrestronInvoke.BeginInvoke((o) => PostStatusMessage(state));
-/* var directoryMessage = new
- {
- currentDirectory = new
- {
- directoryResults = prefixedDirectoryResults,
- isRootDirectory = isRoot
- }
- };
-
- //Spool up a thread in case this is a large quantity of data
- CrestronInvoke.BeginInvoke((o) => PostStatusMessage(directoryMessage)); */
- }
- }
-
- ///
- /// Iterates a directory object and prefixes any folder items with "[+] "
- ///
- ///
- ///
- [Obsolete("Deprected in favour of processing in the Angular App")]
- private CodecDirectory PrefixDirectoryFolderItems(CodecDirectory directory)
- {
- var tempCodecDirectory = new CodecDirectory();
- var tempDirectoryList = new List();
-
- if (directory.CurrentDirectoryResults.Count > 0)
- {
- foreach (var item in directory.CurrentDirectoryResults)
- {
- if (item is DirectoryFolder)
- {
- var newFolder = (DirectoryFolder) item.Clone();
-
- var prefixName = "[+] " + newFolder.Name;
-
- newFolder.Name = prefixName;
-
- tempDirectoryList.Add(newFolder);
- }
- else
- {
- tempDirectoryList.Add(item);
- }
- }
+ /* var directoryMessage = new
+ {
+ currentDirectory = new
+ {
+ directoryResults = prefixedDirectoryResults,
+ isRootDirectory = isRoot
+ }
+ };
+
+ //Spool up a thread in case this is a large quantity of data
+ CrestronInvoke.BeginInvoke((o) => PostStatusMessage(directoryMessage)); */
}
- //else
- //{
- // DirectoryItem noResults = new DirectoryItem() { Name = "No Results Found" };
-
- // tempDirectoryList.Add(noResults);
- //}
-
- tempCodecDirectory.AddContactsToDirectory(tempDirectoryList.OfType().Cast().ToList());
- tempCodecDirectory.AddFoldersToDirectory(tempDirectoryList.OfType().Cast().ToList());
-
- return tempCodecDirectory;
}
///
@@ -189,11 +136,12 @@ private CodecDirectory PrefixDirectoryFolderItems(CodecDirectory directory)
///
///
///
- private void codec_IsReadyChange(object sender, EventArgs e)
+ private void Codec_IsReadyChange(object sender, EventArgs e)
{
- var state = new VideoCodecBaseStateMessage();
-
- state.IsReady = true;
+ var state = new VideoCodecBaseStateMessage
+ {
+ IsReady = true
+ };
PostStatusMessage(state);
@@ -205,149 +153,186 @@ private void codec_IsReadyChange(object sender, EventArgs e)
///
///
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
{
try
{
- base.CustomRegisterWithAppServer(appServerController);
+ base.RegisterActions();
+
+ AddAction("/isReady", (id, content) => SendIsReady());
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
+
+ AddAction("/dial", (id, content) =>
+ {
+ var value = content.ToObject>();
+
+ Codec.Dial(value.Value);
+ });
+
+ AddAction("/dialMeeting", (id, content) => Codec.Dial(content.ToObject()));
- appServerController.AddAction(String.Format("{0}/isReady", MessagePath), new Action(SendIsReady));
- appServerController.AddAction(String.Format("{0}/fullStatus", MessagePath), new Action(SendFullStatus));
- appServerController.AddAction(String.Format("{0}/dial", MessagePath), new Action(s => Codec.Dial(s)));
- appServerController.AddAction(String.Format("{0}/dialMeeting", MessagePath), new Action(m => Codec.Dial(m)));
- appServerController.AddAction(String.Format("{0}/endCallById", MessagePath), new Action(s =>
+ AddAction("/endCallById", (id, content) =>
{
- var call = GetCallWithId(s);
+ var s = content.ToObject>();
+ var call = GetCallWithId(s.Value);
if (call != null)
Codec.EndCall(call);
- }));
- appServerController.AddAction(MessagePath + "/endAllCalls", new Action(Codec.EndAllCalls));
- appServerController.AddAction(MessagePath + "/dtmf", new Action(s => Codec.SendDtmf(s)));
- appServerController.AddAction(MessagePath + "/rejectById", new Action(s =>
+ });
+
+ AddAction("/endAllCalls", (id, content) => Codec.EndAllCalls());
+
+ AddAction("/dtmf", (id, content) =>
{
- var call = GetCallWithId(s);
+ var s = content.ToObject>();
+ Codec.SendDtmf(s.Value);
+ });
+
+ AddAction("/rejectById", (id, content) =>
+ {
+ var s = content.ToObject>();
+
+ var call = GetCallWithId(s.Value);
if (call != null)
Codec.RejectCall(call);
- }));
- appServerController.AddAction(MessagePath + "/acceptById", new Action(s =>
+ });
+
+ AddAction("/acceptById", (id, content) =>
{
- var call = GetCallWithId(s);
+ var s = content.ToObject>();
+
+ var call = GetCallWithId(s.Value);
if (call != null)
Codec.AcceptCall(call);
- }));
+ });
Codec.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
Codec.SharingSourceFeedback.OutputChange += SharingSourceFeedback_OutputChange;
// Directory actions
- var dirCodec = Codec as IHasDirectory;
- if (dirCodec != null)
+ if (Codec is IHasDirectory dirCodec)
{
- appServerController.AddAction(MessagePath + "/getDirectory", new Action(GetDirectoryRoot));
- appServerController.AddAction(MessagePath + "/directoryById", new Action(GetDirectory));
- appServerController.AddAction(MessagePath + "/directorySearch", new Action(DirectorySearch));
- appServerController.AddAction(MessagePath + "/directoryBack", new Action(GetPreviousDirectory));
+ AddAction("/getDirectory", (id, content) => GetDirectoryRoot());
+
+ AddAction("/directoryById", (id, content) =>
+ {
+ var msg = content.ToObject>();
+ GetDirectory(msg.Value);
+ });
+
+ AddAction("/directorySearch", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ GetDirectory(msg.Value);
+ });
+
+ AddAction("/directoryBack", (id, content) => GetPreviousDirectory());
dirCodec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
}
// History actions
- var recCodec = Codec as IHasCallHistory;
- if (recCodec != null)
+ if (Codec is IHasCallHistory recCodec)
{
- appServerController.AddAction(MessagePath + "/getCallHistory", new Action(PostCallHistory));
+ AddAction("/getCallHistory", (id, content) => PostCallHistory());
}
- var cameraCodec = Codec as IHasCodecCameras;
- if (cameraCodec != null)
+ if (Codec is IHasCodecCameras cameraCodec)
{
Debug.Console(2, this, "Adding IHasCodecCameras Actions");
- cameraCodec.CameraSelected += cameraCodec_CameraSelected;
+ cameraCodec.CameraSelected += CameraCodec_CameraSelected;
+
+ AddAction("/cameraSelect", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ cameraCodec.SelectCamera(msg.Value);
+ });
- appServerController.AddAction(MessagePath + "/cameraSelect",
- new Action(cameraCodec.SelectCamera));
MapCameraActions();
- var presetsCodec = Codec as IHasCodecRoomPresets;
- if (presetsCodec != null)
+ if (Codec is IHasCodecRoomPresets presetsCodec)
{
Debug.Console(2, this, "Adding IHasCodecRoomPresets Actions");
- presetsCodec.CodecRoomPresetsListHasChanged += presetsCodec_CameraPresetsListHasChanged;
+ presetsCodec.CodecRoomPresetsListHasChanged += PresetsCodec_CameraPresetsListHasChanged;
+
+ AddAction("/cameraPreset", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ presetsCodec.CodecRoomPresetSelect(msg.Value);
+ });
+
+ AddAction("/cameraPresetStore", (id, content) =>
+ {
+ var msg = content.ToObject();
- appServerController.AddAction(MessagePath + "/cameraPreset",
- new Action(presetsCodec.CodecRoomPresetSelect));
- appServerController.AddAction(MessagePath + "/cameraPresetStore",
- new Action(p => presetsCodec.CodecRoomPresetStore(p.ID, p.Description)));
+ presetsCodec.CodecRoomPresetStore(msg.ID, msg.Description);
+ });
}
- var speakerTrackCodec = Codec as IHasCameraAutoMode;
- if (speakerTrackCodec != null)
+ if (Codec is IHasCameraAutoMode speakerTrackCodec)
{
Debug.Console(2, this, "Adding IHasCameraAutoMode Actions");
speakerTrackCodec.CameraAutoModeIsOnFeedback.OutputChange += CameraAutoModeIsOnFeedback_OutputChange;
- appServerController.AddAction(MessagePath + "/cameraModeAuto",
- new Action(speakerTrackCodec.CameraAutoModeOn));
- appServerController.AddAction(MessagePath + "/cameraModeManual",
- new Action(speakerTrackCodec.CameraAutoModeOff));
+ AddAction("/cameraModeAuto", (id, content) => speakerTrackCodec.CameraAutoModeOn());
+
+ AddAction("/cameraModeManual", (id, content) => speakerTrackCodec.CameraAutoModeOff());
}
- var cameraOffCodec = Codec as IHasCameraOff;
- if (cameraOffCodec != null)
+ if (Codec is IHasCameraOff cameraOffCodec)
{
Debug.Console(2, this, "Adding IHasCameraOff Actions");
cameraOffCodec.CameraIsOffFeedback.OutputChange += (CameraIsOffFeedback_OutputChange);
- appServerController.AddAction(MessagePath + "/cameraModeOff",
- new Action(cameraOffCodec.CameraOff));
+ AddAction("/cameraModeOff", (id, content) => cameraOffCodec.CameraOff());
}
}
- var selfViewCodec = Codec as IHasCodecSelfView;
- if (selfViewCodec != null)
+ if (Codec is IHasCodecSelfView selfViewCodec)
{
Debug.Console(2, this, "Adding IHasCodecSelfView Actions");
- appServerController.AddAction(MessagePath + "/cameraSelfView",
- new Action(selfViewCodec.SelfViewModeToggle));
+ AddAction("/cameraSelfView", (id, content) => selfViewCodec.SelfViewModeToggle());
selfViewCodec.SelfviewIsOnFeedback.OutputChange += new EventHandler(SelfviewIsOnFeedback_OutputChange);
}
- var layoutsCodec = Codec as IHasCodecLayouts;
- if (layoutsCodec != null)
+ if (Codec is IHasCodecLayouts layoutsCodec)
{
Debug.Console(2, this, "Adding IHasCodecLayouts Actions");
- appServerController.AddAction(MessagePath + "/cameraRemoteView",
- new Action(layoutsCodec.LocalLayoutToggle));
-
- appServerController.AddAction(MessagePath + "/cameraLayout",
- new Action(layoutsCodec.LocalLayoutToggle));
+ AddAction("/cameraRemoteView", (id, content) => layoutsCodec.LocalLayoutToggle());
+ AddAction("/cameraLayout", (id, content) => layoutsCodec.LocalLayoutToggle());
}
- var pwCodec = Codec as IPasswordPrompt;
- if (pwCodec != null)
+ if (Codec is IPasswordPrompt pwCodec)
{
Debug.Console(2, this, "Adding IPasswordPrompt Actions");
- appServerController.AddAction(MessagePath + "/password", new Action((s) => pwCodec.SubmitPassword(s)));
+ AddAction("/password", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+ pwCodec.SubmitPassword(msg.Value);
+ });
}
- var farEndContentStatus = Codec as IHasFarEndContentStatus;
- if (farEndContentStatus != null)
+ if (Codec is IHasFarEndContentStatus farEndContentStatus)
{
farEndContentStatus.ReceivingContent.OutputChange +=
(sender, args) => PostReceivingContent(args.BoolValue);
@@ -355,13 +340,13 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
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));
+ AddAction("/privacyModeOn", (id, content) => Codec.PrivacyModeOn());
+ AddAction("/privacyModeOff", (id, content) => Codec.PrivacyModeOff());
+ AddAction("/privacyModeToggle", (id, content) => Codec.PrivacyModeToggle());
+ AddAction("/sharingStart", (id, content) => Codec.StartSharing());
+ AddAction("/sharingStop", (id, content) => Codec.StopSharing());
+ AddAction("/standbyOn", (id, content) => Codec.StandbyActivate());
+ AddAction("/standbyOff", (id, content) => Codec.StandbyDeactivate());
}
catch (Exception e)
{
@@ -371,39 +356,45 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
private void SharingSourceFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
- var state = new VideoCodecBaseStateMessage();
- state.SharingSource = e.StringValue;
+ var state = new VideoCodecBaseStateMessage
+ {
+ SharingSource = e.StringValue
+ };
PostStatusMessage(state);
}
private void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
- var state = new VideoCodecBaseStateMessage();
- state.SharingContentIsOn = e.BoolValue;
+ var state = new VideoCodecBaseStateMessage
+ {
+ SharingContentIsOn = e.BoolValue
+ };
PostStatusMessage(state);
}
private void PhonebookSyncState_InitialSyncCompleted(object sender, EventArgs e)
{
- var state = new VideoCodecBaseStateMessage();
- state.InitialPhonebookSyncComplete = true;
+ var state = new VideoCodecBaseStateMessage
+ {
+ InitialPhonebookSyncComplete = true
+ };
PostStatusMessage(state);
}
- void CameraIsOffFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ private void CameraIsOffFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostCameraMode();
}
- void SelfviewIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ private void SelfviewIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
PostCameraSelfView();
}
- private void presetsCodec_CameraPresetsListHasChanged(object sender, EventArgs e)
+ private void PresetsCodec_CameraPresetsListHasChanged(object sender, EventArgs e)
{
PostCameraPresets();
}
@@ -414,7 +405,7 @@ private void CameraAutoModeIsOnFeedback_OutputChange(object sender, FeedbackEven
}
- private void cameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e)
+ private void CameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e)
{
MapCameraActions();
PostSelectedCamera();
@@ -425,92 +416,147 @@ private void cameraCodec_CameraSelected(object sender, CameraSelectedEventArgs e
///
private void MapCameraActions()
{
- var cameraCodec = Codec as IHasCameras;
-
- if (cameraCodec != null && cameraCodec.SelectedCamera != null)
+ if (Codec is IHasCameras cameraCodec && 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)
+ RemoveAction("/cameraUp");
+ RemoveAction("/cameraDown");
+ RemoveAction("/cameraLeft");
+ RemoveAction("/cameraRight");
+ RemoveAction("/cameraZoomIn");
+ RemoveAction("/cameraZoomOut");
+ RemoveAction("/cameraHome");
+
+ if (cameraCodec.SelectedCamera is IHasCameraPtzControl camera)
{
- AppServerController.AddAction(MessagePath + "/cameraUp", new PressAndHoldAction(b =>
+ AddAction("/cameraUp", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) camera.TiltUp();
- else camera.TiltStop();
+ if (b)
+ {
+ camera.TiltUp();
+ return;
+ }
+
+ camera.TiltStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraDown", new PressAndHoldAction(b =>
+
+ AddAction("/cameraDown", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) camera.TiltDown();
- else camera.TiltStop();
+ if (b)
+ {
+ camera.TiltDown();
+ return;
+ }
+
+ camera.TiltStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraLeft", new PressAndHoldAction(b =>
+
+ AddAction("/cameraLeft", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) camera.PanLeft();
- else camera.PanStop();
+ if (b)
+ {
+ camera.PanLeft();
+ return;
+ }
+
+ camera.PanStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraRight", new PressAndHoldAction(b =>
+
+ AddAction("/cameraRight", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) camera.PanRight();
- else camera.PanStop();
+ if (b)
+ {
+ camera.PanRight();
+ return;
+ }
+
+ camera.PanStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraZoomIn", new PressAndHoldAction(b =>
+
+ AddAction("/cameraZoomIn", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) camera.ZoomIn();
- else camera.ZoomStop();
+ if (b)
+ {
+ camera.ZoomIn();
+ return;
+ }
+
+ camera.ZoomStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraZoomOut", new PressAndHoldAction(b =>
+
+ AddAction("/cameraZoomOut", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) camera.ZoomOut();
- else camera.ZoomStop();
+ if (b)
+ {
+ camera.ZoomOut();
+ return;
+ }
+
+ camera.ZoomStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraHome", new Action(camera.PositionHome));
+ AddAction("/cameraHome", (id, content) => camera.PositionHome());
- var focusCamera = cameraCodec as IHasCameraFocusControl;
- AppServerController.RemoveAction(MessagePath + "/cameraAutoFocus");
- AppServerController.RemoveAction(MessagePath + "/cameraFocusNear");
- AppServerController.RemoveAction(MessagePath + "/cameraFocusFar");
+ RemoveAction("/cameraAutoFocus");
+ RemoveAction("/cameraFocusNear");
+ RemoveAction("/cameraFocusFar");
- if (focusCamera != null)
+ if (cameraCodec is IHasCameraFocusControl focusCamera)
{
- AppServerController.AddAction(MessagePath + "/cameraAutoFocus",
- new Action(focusCamera.TriggerAutoFocus));
- AppServerController.AddAction(MessagePath + "/cameraFocusNear", new PressAndHoldAction(b =>
+ AddAction("/cameraAutoFocus", (id, content) => focusCamera.TriggerAutoFocus());
+
+ AddAction("/cameraFocusNear", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) focusCamera.FocusNear();
- else focusCamera.FocusStop();
+ if (b)
+ {
+ focusCamera.FocusNear();
+ return;
+ }
+
+ focusCamera.FocusStop();
}));
- AppServerController.AddAction(MessagePath + "/cameraFocusFar", new PressAndHoldAction(b =>
+
+ AddAction("/cameraFocusFar", (id, content) => HandleCameraPressAndHold(content, (b) =>
{
- if (b) focusCamera.FocusFar();
- else focusCamera.FocusStop();
+ if (b)
+ {
+ focusCamera.FocusFar();
+ return;
+ }
+
+ focusCamera.FocusStop();
}));
}
}
}
}
+ private void HandleCameraPressAndHold(JToken content, Action cameraAction)
+ {
+ var state = content.ToObject>();
+
+ var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
+ if (timerHandler == null)
+ {
+ return;
+ }
+
+ timerHandler(state.Value, cameraAction);
+
+ cameraAction(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
+ }
+
private string GetCameraMode()
{
string m = "";
- var speakerTrackCodec = Codec as IHasCameraAutoMode;
- if (speakerTrackCodec != null)
+ if (Codec is IHasCameraAutoMode speakerTrackCodec)
{
m = speakerTrackCodec.CameraAutoModeIsOnFeedback.BoolValue
? eCameraControlMode.Auto.ToString().ToLower()
: eCameraControlMode.Manual.ToString().ToLower();
}
- var cameraOffCodec = Codec as IHasCameraOff;
- if (cameraOffCodec != null)
+ if (Codec is IHasCameraOff cameraOffCodec)
{
if (cameraOffCodec.CameraIsOffFeedback.BoolValue)
m = eCameraControlMode.Off.ToString().ToLower();
@@ -548,27 +594,13 @@ private CodecActiveCallItem GetCallWithId(string id)
return Codec.ActiveCalls.FirstOrDefault(c => c.Id == id);
}
- ///
- ///
- ///
- ///
- private void DirectorySearch(string s)
- {
- var dirCodec = Codec as IHasDirectory;
- if (dirCodec != null)
- {
- dirCodec.SearchDirectory(s);
- }
- }
-
///
///
///
///
private void GetDirectory(string id)
{
- var dirCodec = Codec as IHasDirectory;
- if (dirCodec == null)
+ if (!(Codec is IHasDirectory dirCodec))
{
return;
}
@@ -580,16 +612,17 @@ private void GetDirectory(string id)
///
private void GetDirectoryRoot()
{
- var dirCodec = Codec as IHasDirectory;
- if (dirCodec == null)
+ if (!(Codec is IHasDirectory dirCodec))
{
// do something else?
return;
}
if (!dirCodec.PhonebookSyncState.InitialSyncComplete)
{
- var state = new VideoCodecBaseStateMessage();
- state.InitialPhonebookSyncComplete = false;
+ var state = new VideoCodecBaseStateMessage
+ {
+ InitialPhonebookSyncComplete = false
+ };
PostStatusMessage(state);
return;
@@ -603,8 +636,7 @@ private void GetDirectoryRoot()
///
private void GetPreviousDirectory()
{
- var dirCodec = Codec as IHasDirectory;
- if (dirCodec == null)
+ if (!(Codec is IHasDirectory dirCodec))
{
return;
}
@@ -615,7 +647,7 @@ private void GetPreviousDirectory()
///
/// Handler for codec changes
///
- private void codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ private void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
SendFullStatus();
}
@@ -627,8 +659,10 @@ private void SendIsReady()
{
var status = new VideoCodecBaseStateMessage();
+ var codecType = Codec.GetType();
+
status.IsReady = Codec.IsReady;
- status.IsZoomRoom = Codec is ZoomRoom;
+ status.IsZoomRoom = codecType.GetInterface("IHasZoomRoomLayouts") != null;
PostStatusMessage(status);
}
@@ -641,29 +675,29 @@ protected VideoCodecBaseStateMessage GetStatus()
{
var status = new VideoCodecBaseStateMessage();
- status.CommMonitor = GetCommunicationMonitorState();
- var camerasCodec = Codec as IHasCodecCameras;
- if (camerasCodec != null)
+ if (Codec is IHasCodecCameras camerasCodec)
{
- status.Cameras = new VideoCodecBaseStateMessage.CameraStatus();
-
- status.Cameras.CameraManualIsSupported = true;
- status.Cameras.CameraAutoIsSupported = Codec.SupportsCameraAutoMode;
- status.Cameras.CameraOffIsSupported = Codec.SupportsCameraOff;
- status.Cameras.CameraMode = GetCameraMode();
- status.Cameras.Cameras = camerasCodec.Cameras;
- status.Cameras.SelectedCamera = GetSelectedCamera(camerasCodec);
+ status.Cameras = new VideoCodecBaseStateMessage.CameraStatus
+ {
+ CameraManualIsSupported = true,
+ CameraAutoIsSupported = Codec.SupportsCameraAutoMode,
+ CameraOffIsSupported = Codec.SupportsCameraOff,
+ CameraMode = GetCameraMode(),
+ Cameras = camerasCodec.Cameras,
+ SelectedCamera = GetSelectedCamera(camerasCodec)
+ };
}
- var directoryCodec = Codec as IHasDirectory;
- if (directoryCodec != null)
+ if (Codec is IHasDirectory directoryCodec)
{
status.HasDirectory = true;
status.HasDirectorySearch = true;
status.CurrentDirectory = directoryCodec.CurrentDirectoryResult;
}
+ var codecType = Codec.GetType();
+
status.CameraSelfViewIsOn = Codec is IHasCodecSelfView && (Codec as IHasCodecSelfView).SelfviewIsOnFeedback.BoolValue;
status.IsInCall = Codec.IsInCall;
status.PrivacyModeIsOn = Codec.PrivacyModeIsOnFeedback.BoolValue;
@@ -677,11 +711,10 @@ protected VideoCodecBaseStateMessage GetStatus()
status.HasRecents = Codec is IHasCallHistory;
status.HasCameras = Codec is IHasCameras;
status.Presets = GetCurrentPresets();
- status.IsZoomRoom = Codec is ZoomRoom;
+ status.IsZoomRoom = codecType.GetInterface("IHasZoomRoomLayouts") != null;
status.ReceivingContent = Codec is IHasFarEndContentStatus && (Codec as IHasFarEndContentStatus).ReceivingContent.BoolValue;
- var meetingInfoCodec = Codec as IHasMeetingInfo;
- if (meetingInfoCodec != null)
+ if (Codec is IHasMeetingInfo meetingInfoCodec)
{
status.MeetingInfo = meetingInfoCodec.MeetingInfo;
}
@@ -703,18 +736,20 @@ protected virtual void SendFullStatus()
private void PostReceivingContent(bool receivingContent)
{
- var state = new VideoCodecBaseStateMessage();
- state.ReceivingContent = receivingContent;
+ var state = new VideoCodecBaseStateMessage
+ {
+ ReceivingContent = receivingContent
+ };
PostStatusMessage(state);
}
private void PostCameraSelfView()
{
- var status = new VideoCodecBaseStateMessage();
-
- status.CameraSelfViewIsOn = Codec is IHasCodecSelfView
- ? (Codec as IHasCodecSelfView).SelfviewIsOnFeedback.BoolValue
- : false;
+ var status = new VideoCodecBaseStateMessage
+ {
+ CameraSelfViewIsOn = Codec is IHasCodecSelfView
+ && (Codec as IHasCodecSelfView).SelfviewIsOnFeedback.BoolValue
+ };
PostStatusMessage(status);
}
@@ -724,9 +759,10 @@ private void PostCameraSelfView()
///
private void PostCameraMode()
{
- var status = new VideoCodecBaseStateMessage();
-
- status.CameraMode = GetCameraMode();
+ var status = new VideoCodecBaseStateMessage
+ {
+ CameraMode = GetCameraMode()
+ };
PostStatusMessage(status);
}
@@ -735,25 +771,27 @@ private void PostSelectedCamera()
{
var camerasCodec = Codec as IHasCodecCameras;
- var status = new VideoCodecBaseStateMessage();
-
- status.Cameras = new VideoCodecBaseStateMessage.CameraStatus() { SelectedCamera = GetSelectedCamera(camerasCodec) };
- status.Presets = GetCurrentPresets();
+ var status = new VideoCodecBaseStateMessage
+ {
+ Cameras = new VideoCodecBaseStateMessage.CameraStatus() { SelectedCamera = GetSelectedCamera(camerasCodec) },
+ Presets = GetCurrentPresets()
+ };
PostStatusMessage(status);
}
private void PostCameraPresets()
{
- var status = new VideoCodecBaseStateMessage();
-
- status.Presets = GetCurrentPresets();
+ var status = new VideoCodecBaseStateMessage
+ {
+ Presets = GetCurrentPresets()
+ };
PostStatusMessage(status);
}
- private VideoCodecBaseStateMessage.CameraStatus.Camera GetSelectedCamera(IHasCodecCameras camerasCodec)
+ private Camera GetSelectedCamera(IHasCodecCameras camerasCodec)
{
- var camera = new VideoCodecBaseStateMessage.CameraStatus.Camera();
+ var camera = new Camera();
if (camerasCodec.SelectedCameraFeedback != null)
camera.Key = camerasCodec.SelectedCameraFeedback.StringValue;
@@ -761,7 +799,7 @@ private VideoCodecBaseStateMessage.CameraStatus.Camera GetSelectedCamera(IHasCod
{
camera.Name = camerasCodec.SelectedCamera.Name;
- camera.Capabilities = new VideoCodecBaseStateMessage.CameraStatus.Camera.CameraCapabilities()
+ camera.Capabilities = new Camera.CameraCapabilities()
{
CanPan = camerasCodec.SelectedCamera.CanPan,
CanTilt = camerasCodec.SelectedCamera.CanTilt,
@@ -773,8 +811,8 @@ private VideoCodecBaseStateMessage.CameraStatus.Camera GetSelectedCamera(IHasCod
if (camerasCodec.ControllingFarEndCameraFeedback != null)
camera.IsFarEnd = camerasCodec.ControllingFarEndCameraFeedback.BoolValue;
-
- return camera;
+
+ return camera;
}
private List GetCurrentPresets()
@@ -799,7 +837,7 @@ public class VideoCodecBaseStateMessage : DeviceStateMessageBase
{
[JsonProperty("calls", NullValueHandling = NullValueHandling.Ignore)]
- public List Calls {get; set;}
+ public List Calls { get; set; }
[JsonProperty("cameraMode", NullValueHandling = NullValueHandling.Ignore)]
public string CameraMode { get; set; }
@@ -888,7 +926,7 @@ public class VideoCodecBaseStateMessage : DeviceStateMessageBase
[JsonProperty("supportsAdHocMeeting", NullValueHandling = NullValueHandling.Ignore)]
public bool? SupportsAdHocMeeting { get; set; }
- public class CameraStatus
+ public class CameraStatus
{
[JsonProperty("cameraManualSupported", NullValueHandling = NullValueHandling.Ignore)]
public bool? CameraManualIsSupported { get; set; }
@@ -943,7 +981,7 @@ public class CameraCapabilities
}
- public class VideoCodecBaseEventMessage: DeviceEventMessageBase
+ public class VideoCodecBaseEventMessage : DeviceEventMessageBase
{
}
diff --git a/3-series/MobileControlConfig.cs b/3-series/MobileControlConfig.cs
index c08659e..937a86a 100644
--- a/3-series/MobileControlConfig.cs
+++ b/3-series/MobileControlConfig.cs
@@ -1,8 +1,6 @@
-using System.Collections.Generic;
-using System.Security.Policy;
-using Crestron.SimplSharp.Ssh.Security;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
+using System.Collections.Generic;
namespace PepperDash.Essentials
{
@@ -22,7 +20,7 @@ public class MobileControlConfig
public MobileControlDirectServerPropertiesConfig DirectServer { get; set; }
[JsonProperty("applicationConfig")]
- public MobileControlApplicationConfig ApplicationConfig{get; set;}
+ public MobileControlApplicationConfig ApplicationConfig { get; set; }
[JsonProperty("enableApiServer")]
public bool EnableApiServer { get; set; }
@@ -37,7 +35,7 @@ public MobileControlConfig()
#if SERIES4
EnableApiServer = true; // default to true
- ApplicationConfig = null;
+ ApplicationConfig = null;
#endif
}
}
@@ -69,7 +67,7 @@ public class MobileControlLoggingConfig
[JsonProperty("port")]
public int Port { get; set; }
-
+
}
public class MobileControlRoomBridgePropertiesConfig
diff --git a/3-series/MobileControlEssentialsConfig.cs b/3-series/MobileControlEssentialsConfig.cs
index d40f299..aab9b53 100644
--- a/3-series/MobileControlEssentialsConfig.cs
+++ b/3-series/MobileControlEssentialsConfig.cs
@@ -1,10 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
+using Newtonsoft.Json;
using PepperDash.Essentials.Core.Config;
-using Newtonsoft.Json;
namespace PepperDash.Essentials
@@ -18,7 +13,7 @@ public class MobileControlEssentialsConfig : EssentialsConfig
public MobileControlRuntimeInfo RuntimeInfo { get; set; }
public MobileControlEssentialsConfig(EssentialsConfig config)
- :base()
+ : base()
{
// TODO: Consider using Reflection to iterate properties
this.Devices = config.Devices;
diff --git a/3-series/MobileControlFactory.cs b/3-series/MobileControlFactory.cs
index a6d8632..ff535f6 100644
--- a/3-series/MobileControlFactory.cs
+++ b/3-series/MobileControlFactory.cs
@@ -1,11 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using PepperDash.Core;
+using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Room.MobileControl;
+using System;
+using System.Collections.Generic;
+using System.Linq;
namespace PepperDash.Essentials
@@ -15,7 +14,7 @@ public class MobileControlFactory : EssentialsPluginDeviceFactory {"appserver", "mobilecontrol", "webserver" };
+ TypeNames = new List { "appserver", "mobilecontrol", "webserver" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -33,12 +32,12 @@ public override EssentialsDevice BuildDevice(DeviceConfig dc)
}
}
- public class MobileControlSimplFactory : EssentialsPluginDeviceFactory
+ public class MobileControlSimplFactory : EssentialsPluginDeviceFactory
{
public MobileControlSimplFactory()
{
MinimumEssentialsFrameworkVersion = "1.12.5";
- TypeNames = new List {"mobilecontrolbridge-ddvc01", "mobilecontrolbridge-simpl"};
+ TypeNames = new List { "mobilecontrolbridge-ddvc01", "mobilecontrolbridge-simpl" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -57,8 +56,11 @@ public override EssentialsDevice BuildDevice(DeviceConfig dc)
return;
}
Debug.Console(0, bridge, "Linking to parent controller");
- bridge.AddParent(parent);
- parent.AddBridge(bridge);
+
+ /*bridge.AddParent(parent);
+ parent.AddBridge(bridge);*/
+
+ parent.AddDeviceMessenger(bridge);
});
return bridge;
diff --git a/3-series/MobileControlSimplDeviceBridge.cs b/3-series/MobileControlSimplDeviceBridge.cs
index 934f54e..f1ebf62 100644
--- a/3-series/MobileControlSimplDeviceBridge.cs
+++ b/3-series/MobileControlSimplDeviceBridge.cs
@@ -1,7 +1,7 @@
-using System;
-using Crestron.SimplSharpPro.EthernetCommunication;
+using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Essentials.Core;
+using System;
namespace PepperDash.Essentials.Room.MobileControl
{
diff --git a/3-series/MobileControlSystemController.cs b/3-series/MobileControlSystemController.cs
index ff688e1..f67ba96 100644
--- a/3-series/MobileControlSystemController.cs
+++ b/3-series/MobileControlSystemController.cs
@@ -1,49 +1,63 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.RegularExpressions;
-using Crestron.SimplSharp;
+using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Net.Http;
-using Crestron.SimplSharp.Net.Https;
using Crestron.SimplSharp.Reflection;
+using Crestron.SimplSharp.WebScripting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.CrestronIO;
+using PepperDash.Essentials.Core.DeviceInfo;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Lighting;
using PepperDash.Essentials.Core.Monitoring;
-using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Core.Queues;
-using PepperDash.Essentials.Room.Config;
+using PepperDash.Essentials.Core.Routing;
+using PepperDash.Essentials.Core.Shades;
+using PepperDash.Essentials.Core.Web;
+using PepperDash.Essentials.Devices.Common.AudioCodec;
+using PepperDash.Essentials.Devices.Common.Cameras;
+using PepperDash.Essentials.Devices.Common.SoftCodec;
+using PepperDash.Essentials.Devices.Common.TouchPanel;
+using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Room.MobileControl;
-using PepperDash.Essentials.Devices.Common.Codec;
+using PepperDash.Essentials.Services;
+using PepperDash.Essentials.WebApiHandlers;
+using Serilog.Events;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
using WebSocketSharp;
+using DisplayBase = PepperDash.Essentials.Devices.Common.Displays.DisplayBase;
+using TwoWayDisplayBase = PepperDash.Essentials.Devices.Common.Displays.TwoWayDisplayBase;
#if SERIES4
-using PepperDash.Essentials.AppServer;
#endif
namespace PepperDash.Essentials
{
- public class MobileControlSystemController : EssentialsDevice, IMobileControl3
+ public class MobileControlSystemController : EssentialsDevice, IMobileControl
{
- //WebSocketClient WSClient;
-
+ private bool _initialized = false;
private const long ServerReconnectInterval = 5000;
private const long PingInterval = 25000;
- private const long ButtonHeartbeatInterval = 1000;
- private readonly Dictionary _actionDictionary =
- new Dictionary(StringComparer.InvariantCultureIgnoreCase);
+ private readonly Dictionary> _actionDictionary =
+ new Dictionary>(StringComparer.InvariantCultureIgnoreCase);
+
+ public Dictionary> ActionDictionary => _actionDictionary;
- private readonly Dictionary _pushedActions = new Dictionary();
private readonly GenericQueue _receiveQueue;
private readonly List _roomBridges = new List();
#if SERIES4
- private readonly Dictionary _deviceMessengers = new Dictionary();
+ private readonly Dictionary _messengers = new Dictionary();
+
+ private readonly Dictionary _defaultMessengers = new Dictionary();
#else
private readonly Dictionary _deviceMessengers = new Dictionary();
#endif
@@ -55,13 +69,21 @@ public class MobileControlSystemController : EssentialsDevice, IMobileControl3
private bool _disableReconnect;
private WebSocket _wsClient2;
+ public MobileControlApiService ApiService { get; private set; }
+
+ public List RoomBridges => _roomBridges;
+
#if SERIES4
- private MobileControlWebsocketServer _directServer;
+ private readonly MobileControlWebsocketServer _directServer;
+
+ public MobileControlWebsocketServer DirectServer => _directServer;
#endif
private readonly CCriticalSection _wsCriticalSection = new CCriticalSection();
public string SystemUrl; //set only from SIMPL Bridge!
+ public bool Connected => _wsClient2 != null && _wsClient2.IsAlive;
+
public string SystemUuid
{
get
@@ -78,7 +100,7 @@ public string SystemUuid
if (!string.IsNullOrEmpty(SystemUrl))
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "No system_url value defined in config or SIMPL Bridge. Unable to connect to Mobile Control.");
- return String.Empty;
+ return string.Empty;
}
var result = Regex.Match(SystemUrl, @"https?:\/\/.*\/systems\/(.*)\/#.*");
@@ -117,14 +139,9 @@ private set
private DateTime _lastAckMessage;
- private CTimer _pingTimer;
-
- ///
- /// Prevents post operations from stomping on each other and getting lost
- ///
- private CEvent _postLockEvent = new CEvent(true, true);
+ public DateTime LastAckMessage => _lastAckMessage;
- private CEvent _registerLockEvent = new CEvent(true, true);
+ private CTimer _pingTimer;
private CTimer _serverReconnectTimer;
private LogLevel _wsLogLevel = LogLevel.Error;
@@ -163,8 +180,438 @@ public MobileControlSystemController(string key, string name, MobileControlConfi
Host = "https://" + Host;
}
+ ApiService = new MobileControlApiService(Host);
+
Debug.Console(0, this, "Mobile UI controller initializing for server:{0}", config.ServerUrl);
+ if (Global.Platform == eDevicePlatform.Appliance)
+ {
+ AddConsoleCommands();
+ }
+
+ AddPreActivationAction(() => LinkSystemMonitorToAppServer());
+
+ AddPreActivationAction(() => SetupDefaultDeviceMessengers());
+
+ AddPreActivationAction(() => SetupDefaultRoomMessengers());
+
+ AddPreActivationAction(() => AddWebApiPaths());
+
+ CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
+
+ ApiOnlineAndAuthorized = new BoolFeedback(() =>
+ {
+ if (_wsClient2 == null)
+ return false;
+
+ return _wsClient2.IsAlive && IsAuthorized;
+ });
+ }
+
+ private void SetupDefaultRoomMessengers()
+ {
+ foreach (var room in DeviceManager.AllDevices.OfType())
+ {
+ var messenger = new MobileControlEssentialsRoomBridge(room);
+
+ _roomBridges.Add(messenger);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ Debug.Console(2, this, "Attempting to set up room messengers for room: {0}", room.Key);
+
+ if (room is IRoomEventSchedule)
+ {
+ var scheduleMessenger = new RoomEventScheduleMessenger($"{room.Key}-schedule-{Key}",
+
+ string.Format("/room/{0}", room.Key), room as IRoomEventSchedule);
+
+ AddDefaultDeviceMessenger(scheduleMessenger);
+ }
+
+ if (room is ITechPassword)
+ {
+ var techPasswordMessenger = new ITechPasswordMessenger($"{room.Key}-techPassword-{Key}",
+ string.Format("/room/{0}", room.Key), room as ITechPassword);
+
+ AddDefaultDeviceMessenger(techPasswordMessenger);
+ }
+
+ if (room is IShutdownPromptTimer)
+ {
+ var shutdownPromptTimerMessenger = new IShutdownPromptTimerMessenger($"{room.Key}-shutdownPromptTimer-{Key}",
+ string.Format("/room/{0}", room.Key), room as IShutdownPromptTimer);
+
+ AddDefaultDeviceMessenger(shutdownPromptTimerMessenger);
+ }
+ }
+ }
+
+ ///
+ /// Set up the messengers for each device type
+ ///
+ private void SetupDefaultDeviceMessengers()
+ {
+ bool messengerAdded = false;
+ foreach (var device in DeviceManager.AllDevices.Where((d) => !(d is IEssentialsRoom)).Cast())
+ {
+ Debug.Console(2, this, "Attempting to set up device messengers for device: {0}", device.Key);
+
+
+ if (device is ICommunicationMonitor)
+ {
+ Debug.Console(2, this, "Adding CommunicationMonitorMessenger for device: {0}", device.Key);
+ var commMessenger = new ICommunicationMonitorMessenger($"{device.Key}-commMonitor-{Key}",
+ string.Format("/device/{0}", device.Key), device as ICommunicationMonitor);
+ AddDefaultDeviceMessenger(commMessenger);
+ messengerAdded = true;
+ }
+
+ if (device is CameraBase)
+ {
+ Debug.Console(2, this, "Adding CameraBaseMessenger for device: {0}", device.Key);
+
+ var cameraMessenger = new CameraBaseMessenger($"{device.Key}-cameraBase-{Key}", device as CameraBase,
+ $"/device/{device.Key}");
+
+ AddDefaultDeviceMessenger(cameraMessenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is BlueJeansPc)
+ {
+ Debug.Console(2, this, "Adding IRunRouteActionMessnger for device: {0}", device.Key);
+
+ var routeMessenger = new RunRouteActionMessenger($"{device.Key}-runRouteAction-{Key}", device as BlueJeansPc,
+ $"/device/{device.Key}");
+
+ AddDefaultDeviceMessenger(routeMessenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is ITvPresetsProvider)
+ {
+ var presetsDevice = device as ITvPresetsProvider;
+
+ if (presetsDevice.TvPresets == null)
+ {
+ Debug.Console(2, this, "TvPresets is null for device: '{0}'. Skipping DevicePresetsModelMessenger", device.Key);
+ }
+ else
+ {
+ Debug.Console(2, this, "Adding ITvPresetsProvider for device: {0}", device.Key);
+
+ var presetsMessenger = new DevicePresetsModelMessenger($"{device.Key}-presets-{Key}", $"/device/{device.Key}/presets",
+ presetsDevice);
+
+ AddDefaultDeviceMessenger(presetsMessenger);
+
+ messengerAdded = true;
+ }
+ }
+
+ if (device is DisplayBase)
+ {
+
+ Debug.Console(2, this, "Adding actions for device: {0}", device.Key);
+
+ var dbMessenger = new DisplayBaseMessenger($"{device.Key}-displayBase-{Key}", $"/device/{device.Key}", device as DisplayBase);
+
+ AddDefaultDeviceMessenger(dbMessenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is Core.DisplayBase)
+ {
+ Debug.Console(2, this, "Adding actions for device: {0}", device.Key);
+
+ var dbMessenger = new CoreDisplayBaseMessenger($"{device.Key}-displayBase-{Key}", $"/device/{device.Key}", device as Core.DisplayBase);
+ AddDefaultDeviceMessenger(dbMessenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is TwoWayDisplayBase)
+ {
+ var display = device as TwoWayDisplayBase;
+ Debug.Console(2, this, "Adding TwoWayDisplayBase for device: {0}", device.Key);
+ var twoWayDisplayMessenger = new TwoWayDisplayBaseMessenger($"{device.Key}-twoWayDisplay-{Key}",
+ string.Format("/device/{0}", device.Key), display);
+ AddDefaultDeviceMessenger(twoWayDisplayMessenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is Core.TwoWayDisplayBase)
+ {
+ var display = device as Core.TwoWayDisplayBase;
+ Debug.Console(2, this, "Adding TwoWayDisplayBase for device: {0}", device.Key);
+ var twoWayDisplayMessenger = new CoreTwoWayDisplayBaseMessenger($"{device.Key}-twoWayDisplay-{Key}",
+ string.Format("/device/{0}", device.Key), display);
+ AddDefaultDeviceMessenger(twoWayDisplayMessenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IBasicVolumeWithFeedback)
+ {
+ var deviceKey = device.Key;
+ var volControlDevice = device as IBasicVolumeWithFeedback;
+ Debug.Console(2, this, "Adding IBasicVolumeControlWithFeedback for device: {0}", deviceKey);
+ var messenger = new DeviceVolumeMessenger($"{device.Key}-volume-{Key}",
+ string.Format("/device/{0}", deviceKey), volControlDevice);
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is ILightingScenes)
+ {
+ var deviceKey = device.Key;
+ var lightingDevice = device as ILightingScenes;
+ Debug.Console(2, this, "Adding LightingBaseMessenger for device: {0}", deviceKey);
+ var messenger = new ILightingScenesMessenger($"{device.Key}-lighting-{Key}",
+ lightingDevice, string.Format("/device/{0}", deviceKey));
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IShadesOpenCloseStop)
+ {
+ var deviceKey = device.Key;
+ var shadeDevice = device as IShadesOpenCloseStop;
+ Debug.Console(2, this, "Adding ShadeBaseMessenger for device: {0}", deviceKey);
+ var messenger = new IShadesOpenCloseStopMessenger($"{device.Key}-shades-{Key}",
+ shadeDevice, string.Format("/device/{0}", deviceKey));
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is VideoCodecBase codec)
+ {
+ Debug.Console(2, this, $"Adding VideoCodecBaseMessenger for device: {codec.Key}");
+
+ var messenger = new VideoCodecBaseMessenger($"{codec.Key}-videoCodec-{Key}", codec, $"/device/{codec.Key}");
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is AudioCodecBase audioCodec) {
+ Debug.Console(2, this, $"Adding AudioCodecBaseMessenger for device: {audioCodec.Key}");
+
+ var messenger = new AudioCodecBaseMessenger($"{audioCodec.Key}-audioCodec-{Key}", audioCodec, $"/device/{audioCodec.Key}");
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is ISetTopBoxControls)
+ {
+ Debug.Console(2, this, $"Adding ISetTopBoxControlMessenger for device: {device.Key}");
+
+ var messenger = new ISetTopBoxControlsMessenger($"{device.Key}-stb-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IChannel)
+ {
+ Debug.Console(2, this, $"Adding IChannelMessenger for device: {device.Key}");
+
+ var messenger = new IChannelMessenger($"{device.Key}-channel-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IColor)
+ {
+ Debug.Console(2, this, $"Adding IColorMessenger for device: {device.Key}");
+
+ var messenger = new IColorMessenger($"{device.Key}-color-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IDPad)
+ {
+ Debug.Console(2, this, $"Adding IDPadMessenger for device: {device.Key}");
+
+ var messenger = new IDPadMessenger($"{device.Key}-dPad-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is INumericKeypad)
+ {
+ Debug.Console(2, this, $"Adding INumericKeyapdMessenger for device: {device.Key}");
+
+ var messenger = new INumericKeypadMessenger($"{device.Key}-numericKeypad-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IHasPowerControl)
+ {
+ Debug.Console(2, this, $"Adding IHasPowerControlMessenger for device: {device.Key}");
+
+ var messenger = new IHasPowerMessenger($"{device.Key}-powerControl-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is IHasPowerControlWithFeedback powerControl)
+ {
+ var deviceKey = device.Key;
+ Debug.Console(2, this, "Adding IHasPowerControlWithFeedbackMessenger for device: {0}", deviceKey);
+ var messenger = new IHasPowerControlWithFeedbackMessenger($"{device.Key}-powerFeedback-{Key}",
+ string.Format("/device/{0}", deviceKey), powerControl);
+ AddDefaultDeviceMessenger(messenger);
+ messengerAdded = true;
+ }
+
+ if (device is ITransport)
+ {
+ Debug.Console(2, this, $"Adding ITransportMessenger for device: {device.Key}");
+
+ var messenger = new IChannelMessenger($"{device.Key}-transport-{Key}", $"/device/{device.Key}", device);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is IHasCurrentSourceInfoChange)
+ {
+ Debug.Console(2, this, $"Adding IHasCurrentSourceInfoMessenger for device: {device.Key}");
+
+ var messenger = new IHasCurrentSourceInfoMessenger($"{device.Key}-currentSource-{Key}", $"/device/{device.Key}", device as IHasCurrentSourceInfoChange);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (device is ISwitchedOutput)
+ {
+ Debug.Console(2, this, $"Adding ISwitchedOutputMessenger for device: {device.Key}");
+
+ var messenger = new ISwitchedOutputMessenger($"{device.Key}-switchedOutput-{Key}", device as ISwitchedOutput, $"/device/{device.Key}");
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is IDeviceInfoProvider provider)
+ {
+ Debug.Console(2, this, $"Adding IHasDeviceInfoMessenger for device: {device.Key}");
+
+ var messenger = new DeviceInfoMessenger($"{device.Key}-deviceInfo-{Key}", $"/device/{device.Key}", provider);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is ILevelControls levelControls)
+ {
+ Debug.Console(2, this, $"Adding LevelControlsMessenger for device: {device.Key}");
+
+ var messenger = new ILevelControlsMessenger($"{device.Key}-levelControls-{Key}", $"/device/{device.Key}", levelControls);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ // This will work if TKey and TSelector are both string types.
+ // Otherwise plugin device needs to instantiate ISelectableItemsMessenger and add it to the controller.
+ if(device is IHasInputs inputs)
+ {
+ Debug.Console(2, this, $"Adding InputsMessenger for device: {device.Key}");
+
+ var messenger = new ISelectableItemsMessenger($"{device.Key}-inputs-{Key}", $"/device/{device.Key}", inputs.Inputs, "inputs");
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if(device is IMatrixRouting matrix)
+ {
+ Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, "Adding IMatrixRoutingMessenger for device: {key}", this, device.Key);
+
+ var messenger = new IMatrixRoutingMessenger($"{device.Key}-matrixRouting", $"/device/{device.Key}", matrix);
+
+ AddDefaultDeviceMessenger(messenger);
+
+ messengerAdded = true;
+ }
+
+ if (!(device is EssentialsDevice genericDevice) || messengerAdded)
+ {
+ continue;
+ }
+
+ Debug.Console(2, this, "Adding GenericMessenger for device: {0}", genericDevice.Key);
+ AddDefaultDeviceMessenger(new GenericMessenger(genericDevice.Key + "-" + Key + "-generic", genericDevice, string.Format("/device/{0}", genericDevice.Key)));
+ }
+ }
+
+ private void AddWebApiPaths()
+ {
+ var apiServer = DeviceManager.AllDevices.OfType().FirstOrDefault(d => d.Key == "essentialsWebApi");
+
+ if (apiServer == null)
+ {
+ Debug.Console(0, this, "No API Server available");
+ return;
+ }
+
+ var routes = new List
+ {
+ new HttpCwsRoute($"device/{Key}/authorize")
+ {
+ Name = "MobileControlAuthorize",
+ RouteHandler = new MobileAuthRequestHandler(this)
+ },
+ new HttpCwsRoute($"device/{Key}/info")
+ {
+ Name = "MobileControlInformation",
+ RouteHandler = new MobileInfoHandler(this)
+ },
+ new HttpCwsRoute($"device/{Key}/actionPaths")
+ {
+ Name = "MobileControlActionPaths",
+ RouteHandler = new ActionPathsHandler(this)
+ }
+ };
+
+ apiServer.AddRoute(routes);
+ }
+
+ private void AddConsoleCommands()
+ {
CrestronConsole.AddNewConsoleCommand(AuthorizeSystem,
"mobileauth", "Authorizes system to talk to Mobile Control server",
ConsoleAccessLevelEnum.AccessOperator);
@@ -207,36 +654,22 @@ public MobileControlSystemController(string key, string name, MobileControlConfi
CrestronConsole.AddNewConsoleCommand(SetWebsocketDebugLevel, "mobilewsdebug", "Set Websocket debug level",
ConsoleAccessLevelEnum.AccessProgrammer);
-
- CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
-
- // Config Messenger
- //var cmKey = Key + "-config";
- //ConfigMessenger = new ConfigMessenger(cmKey, "/config");
- //ConfigMessenger.RegisterWithAppServer(this);
-
- ApiOnlineAndAuthorized = new BoolFeedback(() => {
- if(_wsClient2 == null)
- return false;
-
- return _wsClient2.IsAlive && IsAuthorized;
- });
}
public MobileControlConfig Config { get; private set; }
public string Host { get; private set; }
- //public ConfigMessenger ConfigMessenger { get; private set; }
-
+
+ public string ClientAppUrl => Config.ClientAppUrl;
private void RoomCombinerOnRoomCombinationScenarioChanged(object sender, EventArgs eventArgs)
{
- SendMessageObject(new {type = "/system/roomCombinationChanged"});
+ SendMessageObject(new MobileControlMessage { Type = "/system/roomCombinationChanged" });
}
public bool CheckForDeviceMessenger(string key)
{
- return _deviceMessengers.ContainsKey(key);
+ return _messengers.ContainsKey(key);
}
#if SERIES4
@@ -245,49 +678,102 @@ public void AddDeviceMessenger(IMobileControlMessenger messenger)
public void AddDeviceMessenger(MessengerBase messenger)
#endif
{
- if (_deviceMessengers.ContainsKey(messenger.Key))
+ if (_messengers.ContainsKey(messenger.Key))
{
Debug.Console(1, this, "Messenger with key {0} already added", messenger.Key);
return;
}
- if(_deviceMessengers.Any((kv) => kv.Value.MessagePath.Equals(messenger.MessagePath, StringComparison.InvariantCulture))) {
- Debug.Console(1, this, "Messenger with path {0} alread added", messenger.MessagePath);
- return;
+ if (messenger is IDelayedConfiguration simplMessenger)
+ {
+ simplMessenger.ConfigurationIsReady += Bridge_ConfigurationIsReady;
+ }
+
+ if (messenger is MobileControlBridgeBase roomBridge)
+ {
+ _roomBridges.Add(roomBridge);
}
Debug.Console(2, this, "Adding messenger with key {0} for path {1}", messenger.Key, messenger.MessagePath);
- _deviceMessengers.Add(messenger.Key, messenger);
+ _messengers.Add(messenger.Key, messenger);
messenger.RegisterWithAppServer(this);
}
- private void CreateMobileControlRoomBridges()
+ private void AddDefaultDeviceMessenger(IMobileControlMessenger messenger)
{
- if (Config.RoomBridges.Count == 0)
+ if (_defaultMessengers.ContainsKey(messenger.Key))
{
- Debug.Console(0, this, "No Room bridges configured explicitly. Bridges will be created for each configured room.");
+ Debug.Console(1, this, "Default messenger with key {0} already added", messenger.Key);
return;
}
- foreach (var bridge in Config.RoomBridges.Select(bridgeConfig =>
- new MobileControlEssentialsRoomBridge(bridgeConfig.Key, bridgeConfig.RoomKey, DeviceManager.GetDeviceForKey(bridgeConfig.RoomKey) as Device)))
+ if (messenger is IDelayedConfiguration simplMessenger)
{
- AddBridgePostActivationAction(bridge);
- DeviceManager.AddDevice(bridge);
+ simplMessenger.ConfigurationIsReady += Bridge_ConfigurationIsReady;
}
+ Debug.Console(2, this, "Adding default messenger with key {0} for path {1}", messenger.Key, messenger.MessagePath);
+
+ _defaultMessengers.Add(messenger.Key, messenger);
+
+ if (_initialized)
+ {
+ RegisterMessengerWithServer(messenger);
+ }
}
- #region IMobileControl Members
+ private void RegisterMessengerWithServer(IMobileControlMessenger messenger)
+ {
+ Debug.Console(2, this, "Registering messenger with key {0} for path {1}", messenger.Key, messenger.MessagePath);
+
+ messenger.RegisterWithAppServer(this);
+ }
- public void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent)
+ public override void Initialize()
{
- var bridge = new MobileControlEssentialsRoomBridge(room);
- AddBridgePostActivationAction(bridge);
- DeviceManager.AddDevice(bridge);
+ foreach (var messenger in _messengers)
+ {
+ try
+ {
+ RegisterMessengerWithServer(messenger.Value);
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, this, $"Exception registering paths for {messenger.Key}: {ex.Message}");
+ Debug.Console(2, this, $"Exception registering paths for {messenger.Key}: {ex.StackTrace}");
+ continue;
+ }
+ }
+
+ foreach (var messenger in _defaultMessengers)
+ {
+ try
+ {
+ RegisterMessengerWithServer(messenger.Value);
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, this, $"Exception registering paths for {messenger.Key}: {ex.Message}");
+ Debug.Console(2, this, $"Exception registering paths for {messenger.Key}: {ex.StackTrace}");
+ continue;
+ }
+ }
+
+ var simplMessengers = _messengers.OfType().ToList();
+
+ if (simplMessengers.Count > 0)
+ {
+ return;
+ }
+
+ _initialized = true;
+
+ RegisterSystemToServer();
}
+ #region IMobileControl Members
+
public static IMobileControl GetAppServer()
{
try
@@ -313,7 +799,7 @@ private bool CreateWebsocket()
_wsClient2 = null;
}
- if (String.IsNullOrEmpty(SystemUuid))
+ if (string.IsNullOrEmpty(SystemUuid))
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "System UUID not defined. Unable to connect to Mobile Control");
return false;
@@ -331,6 +817,8 @@ private bool CreateWebsocket()
}
};
+ _wsClient2.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls12;
+
_wsClient2.OnMessage += HandleMessage;
_wsClient2.OnOpen += HandleOpen;
_wsClient2.OnError += HandleError;
@@ -348,29 +836,23 @@ public void LinkSystemMonitorToAppServer()
return;
}
- var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as SystemMonitorController;
-
- var appServer = GetAppServer() as MobileControlSystemController;
-
- if (sysMon == null || appServer == null)
+ if (!(DeviceManager.GetDeviceForKey("systemMonitor") is SystemMonitorController sysMon))
{
return;
}
- var key = sysMon.Key + "-" + appServer.Key;
+ var key = sysMon.Key + "-" + Key;
var messenger = new SystemMonitorMessenger(key, sysMon, "/device/systemMonitor");
- messenger.RegisterWithAppServer(appServer);
-
- DeviceManager.AddDevice(messenger);
+ AddDeviceMessenger(messenger);
}
- public void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent)
- {
- var bridge = new MobileControlEssentialsRoomBridge(room);
- AddBridgePostActivationAction(bridge);
- DeviceManager.AddDevice(bridge);
- }
+ /* public void CreateMobileControlRoomBridge(IEssentialsRoom room, IMobileControl parent)
+ {
+ var bridge = new MobileControlEssentialsRoomBridge(room);
+ AddBridgePostActivationAction(bridge);
+ DeviceManager.AddDevice(bridge);
+ } */
#endregion
@@ -382,7 +864,7 @@ private void SetWebsocketDebugLevel(string cmdparameters)
return; // Web socket log level not currently allowed in series4
}
- if (String.IsNullOrEmpty(cmdparameters))
+ if (string.IsNullOrEmpty(cmdparameters))
{
Debug.Console(0, this, "Current Websocket debug level: {0}", _wsLogLevel);
return;
@@ -396,7 +878,7 @@ private void SetWebsocketDebugLevel(string cmdparameters)
try
{
- var debugLevel = (LogLevel) Enum.Parse(typeof (LogLevel), cmdparameters, true);
+ var debugLevel = (LogLevel)Enum.Parse(typeof(LogLevel), cmdparameters, true);
_wsLogLevel = debugLevel;
@@ -404,48 +886,26 @@ private void SetWebsocketDebugLevel(string cmdparameters)
{
_wsClient2.Log.Level = _wsLogLevel;
}
-
+
Debug.Console(0, this, "Websocket log level set to {0}", debugLevel);
}
catch
{
- Debug.Console(0, this, "{0} is not a valid debug level. Valid options are: {1}, {2}, {3}, {4}, {5}, {6}",cmdparameters,
+ Debug.Console(0, this, "{0} is not a valid debug level. Valid options are: {1}, {2}, {3}, {4}, {5}, {6}", cmdparameters,
LogLevel.Trace, LogLevel.Debug, LogLevel.Info, LogLevel.Warn, LogLevel.Error, LogLevel.Fatal);
}
}
- private void AddBridgePostActivationAction(MobileControlBridgeBase bridge)
- {
- bridge.AddPostActivationAction(() =>
- {
- Debug.Console(0, bridge, "Linking to parent controller");
- bridge.AddParent(this);
- AddBridge(bridge);
- });
- }
-
- ///
- /// If config rooms is empty or null then go
- ///
- ///
- public override bool CustomActivate()
- {
- if (ConfigReader.ConfigObject.Rooms != null && ConfigReader.ConfigObject.Rooms.Count != 0)
- {
- return base.CustomActivate();
- }
-
- if (_roomBridges.OfType().ToList().Count > 0)
- {
- return base.CustomActivate();
- }
-
- Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Config contains no rooms. Registering with Server.");
- RegisterSystemToServer();
-
- return base.CustomActivate();
- }
+ /* private void AddBridgePostActivationAction(MobileControlBridgeBase bridge)
+ {
+ bridge.AddPostActivationAction(() =>
+ {
+ Debug.Console(0, bridge, "Linking to parent controller");
+ bridge.AddParent(this);
+ AddBridge(bridge);
+ });
+ }*/
///
/// Sends message to server to indicate the system is shutting down
@@ -466,12 +926,31 @@ private void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventTy
public void PrintActionDictionaryPaths(object o)
{
- Debug.Console(0, this, "ActionDictionary Contents:");
+ CrestronConsole.ConsoleCommandResponse("ActionDictionary Contents:\r\n");
+
+ foreach(var (messengerKey, actionPath) in GetActionDictionaryPaths())
+ {
+ CrestronConsole.ConsoleCommandResponse($"<{messengerKey}> {actionPath}\r\n");
+ }
+ }
+
+ public List<(string, string)> GetActionDictionaryPaths()
+ {
+ var paths = new List<(string, string)>();
foreach (var item in _actionDictionary)
{
- Debug.Console(0, this, "{0}", item.Key);
+ var messengers = item.Value.Select(a => a.Messenger).Cast();
+ foreach (var messenger in messengers)
+ {
+ foreach (var actionPath in messenger.GetActionPaths())
+ {
+ paths.Add((messenger.Key, $"{item.Key}{actionPath}"));
+ }
+ }
}
+
+ return paths;
}
///
@@ -479,17 +958,27 @@ public void PrintActionDictionaryPaths(object o)
///
/// The path of the API command
/// The action to be triggered by the commmand
- public void AddAction(string key, object action)
+ public void AddAction(T messenger, Action action) where T:IMobileControlMessenger
{
- if (!_actionDictionary.ContainsKey(key))
+ if (_actionDictionary.TryGetValue(messenger.MessagePath, out List actionList))
{
- _actionDictionary.Add(key, action);
+
+ if(actionList.Any(a => a.Messenger.GetType() == messenger.GetType() && a.Messenger.DeviceKey == messenger.DeviceKey))
+ {
+ Debug.Console(0, this, $"Messenger of type {messenger.GetType().Name} already exists. Skipping actions for {messenger.Key}");
+ return;
+ }
+
+ actionList.Add(new MobileControlAction(messenger, action));
+ return;
}
- else
+
+ actionList = new List
{
- Debug.Console(1, this,
- "Cannot add action with key '{0}' because key already exists in ActionDictionary.", key);
- }
+ new MobileControlAction(messenger, action)
+ };
+
+ _actionDictionary.Add(messenger.MessagePath, actionList);
}
///
@@ -504,28 +993,12 @@ public void RemoveAction(string key)
}
}
- ///
- ///
- ///
- ///
- public void AddBridge(MobileControlBridgeBase bridge)
+ public MobileControlBridgeBase GetRoomBridge(string key)
{
- _roomBridges.Add(bridge);
- var b = bridge as IDelayedConfiguration;
- if (b != null)
- {
- Debug.Console(0, this, "Adding room bridge with delayed configuration");
- b.ConfigurationIsReady += bridge_ConfigurationIsReady;
- }
- else
- {
- Debug.Console(0, this, "Adding room bridge and sending configuration");
-
- RegisterSystemToServer();
- }
+ return _roomBridges.FirstOrDefault((r) => r.RoomKey.Equals(key));
}
- public MobileControlBridgeBase GetRoomBridge(string key)
+ public IMobileControlRoomMessenger GetRoomMessenger(string key)
{
return _roomBridges.FirstOrDefault((r) => r.RoomKey.Equals(key));
}
@@ -535,7 +1008,7 @@ public MobileControlBridgeBase GetRoomBridge(string key)
///
///
///
- private void bridge_ConfigurationIsReady(object sender, EventArgs e)
+ private void Bridge_ConfigurationIsReady(object sender, EventArgs e)
{
Debug.Console(1, this, "Bridge ready. Registering");
@@ -553,7 +1026,7 @@ private void bridge_ConfigurationIsReady(object sender, EventArgs e)
{
SendInitialMessage();
}
-
+
}
///
@@ -563,7 +1036,6 @@ private void bridge_ConfigurationIsReady(object sender, EventArgs e)
private void ReconnectToServerTimerCallback(object o)
{
Debug.Console(1, this, "Attempting to reconnect to server...");
- //RegisterSystemToServer();
ConnectWebsocketClient();
}
@@ -587,190 +1059,27 @@ private void AuthorizeSystem(string code)
if (string.IsNullOrEmpty(Config.ServerUrl))
{
CrestronConsole.ConsoleCommandResponse(
- "Mobile control API address is not set. Check portal configuration");
+ "Mobile control API address is not set. Check portal configuration");
return;
}
+ var authTask = ApiService.SendAuthorizationRequest(Host, code, SystemUuid);
- try
+ authTask.ContinueWith(t =>
{
- string path = string.Format("/api/system/grantcode/{0}/{1}", code, SystemUuid);
- string url = string.Format("{0}{1}", Host, path);
- Debug.Console(0, this, "Authorizing to: {0}", url);
+ var response = t.Result;
- if (Host.StartsWith("https:"))
- {
- DispatchHttpsAuthorizationRequest(url);
- }
- else
+ if (response.Authorized)
{
- var req = new HttpClientRequest();
- req.Url.Parse(url);
-
- var c = new HttpClient {AllowAutoRedirect = false};
- c.DispatchAsync(req, (r, e) =>
- {
- CheckHttpDebug(r, e);
- if (e == HTTP_CALLBACK_ERROR.COMPLETED)
- {
- switch (r.Code)
- {
- case 200:
- Debug.Console(0, "System authorized, sending config.");
- RegisterSystemToServer();
- break;
- case 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);
- }
- break;
- case 301:
- {
- var newUrl = r.Header.GetHeaderValue("Location");
- var newHostValue = newUrl.Substring(0,
- newUrl.IndexOf(path, StringComparison.Ordinal));
- Debug.Console(0, this,
- "ERROR: Mobile control API has moved. Please adjust configuration to \"{0}\"",
- newHostValue);
- }
- break;
- default:
- Debug.Console(0, "http authorization failed, code {0}: {1}", r.Code, r.ContentString);
- break;
- }
- }
- else
- {
- if (r != null)
- {
- Debug.Console(0, this, "Error in http authorization (A) {0}: {1}", r.Code, e);
- }
- else
- {
- Debug.Console(0, this, "Error in http authorization (B) {0}", e);
- }
- }
- });
+ Debug.Console(0, this, "System authorized, sending config.");
+ RegisterSystemToServer();
+ return;
}
- }
- catch (Exception e)
- {
- Debug.Console(0, this, "Error in authorizing (C): {0}", e.Message);
- }
- }
-
- ///
- /// Dispatchs and handles an Https Authorization Request
- ///
- /// Url to dispatch request to
- private void DispatchHttpsAuthorizationRequest(string url)
- {
- var req = new HttpsClientRequest();
- req.Url.Parse(url);
-
- var JsonHeader = new HttpsHeader("content-type", "application/json");
-
- req.ContentString = "SOME STUFF HERE";
- var c = new HttpsClient {HostVerification = false, PeerVerification = false, Verbose = true};
-
- c.DispatchAsync(req, (r, e) =>
- {
- if (e == HTTPS_CALLBACK_ERROR.COMPLETED)
- {
- ProcessAuthorizationResponse(r);
- }
- else
- {
- if (r != null)
- {
- Debug.Console(0, this, "Error in http authorization (A) {0}: {1}", r.Code, e);
- }
- else
- {
- Debug.Console(0, this, "Error in http authorization (B) {0}", e);
- }
- }
+ Debug.Console(0, this, response.Reason);
});
}
- private void MyCallBackResponseHandler(HttpsClientResponse r, HTTPS_CALLBACK_ERROR e)
- {
- if (r.Code != 200)
- {
- Debug.Console(2, this, "Print Error {0}", e);
- }
- else
- {
- Debug.Console(2, this, "Got valid response {0}", r.Code);
- }
-
- }
-
- ///
- /// Processes HttpsClientResponse and registers system to server as necessary
- ///
- /// Response from authorization request
- private void ProcessAuthorizationResponse(HttpsClientResponse r)
- {
- if (r.Code == 200)
- {
- Debug.Console(0, "System authorized, sending config.");
- RegisterSystemToServer();
- }
- else if (r.Code == 404 && String.IsNullOrEmpty(r.ContentString))
- {
- Debug.Console(0, "https authorization failed, code {0}", r.Code);
- if (String.IsNullOrEmpty(r.ContentString))
- {
- Debug.Console(0, "content: {0}", r.ContentString);
- }
-
- if (r.ContentString.Contains("codeNotFound"))
- {
- Debug.Console(0, "code not found for system UUID {0}",
- SystemUuid);
- }
- else if (r.ContentString.Contains("uuidNotFound"))
- {
- Debug.Console(0,
- "uuid {0} not found. Check Essentials configuration is correct",
- SystemUuid);
- }
- }
- else if (r.Code == 301 && r.Header != null)
- {
- Debug.Console(0, "https authorization failed, code {0}", r.Code);
- if (String.IsNullOrEmpty(r.ContentString))
- {
- Debug.Console(0, "content {0}", r.ContentString);
- }
-
- var newUrl = r.Header.GetHeaderValue("Location");
- var newHostValue = newUrl.Substring(0,
- newUrl.IndexOf(r.ResponseUrl, StringComparison.Ordinal));
- Debug.Console(0, this,
- "ERROR: Mobile control API has moved. Please adjust configuration to \"{0}\"",
- newHostValue);
- }
- else
- {
- Debug.Console(0, "https authorization failed, code {0}", r.Code);
- if (String.IsNullOrEmpty(r.ContentString))
- {
- Debug.Console(0, "Content {0}", r.ContentString);
- }
- }
- }
-
///
/// Dumps info in response to console command.
///
@@ -853,6 +1162,7 @@ Not Enabled in Config.
@"
Client {0}:
Room Key: {1}
+Touchpanel Key: {6}
Token: {2}
Client URL: {3}
Connected: {4}
@@ -863,7 +1173,7 @@ Not Enabled in Config.
clientContext.Key,
string.Format("{0}{1}", _directServer.UserAppUrlPrefix, clientContext.Key),
isAlive,
-duration);
+duration, clientContext.Value.Token.TouchpanelKey);
clientNo++;
}
}
@@ -880,7 +1190,7 @@ Not Enabled in Config.
///
/// Registers the room with the server
///
- private void RegisterSystemToServer()
+ public void RegisterSystemToServer()
{
#if SERIES4
if (!Config.EnableApiServer)
@@ -913,15 +1223,13 @@ private void ConnectWebsocketClient()
// set to 99999 to let things work on 4-Series
if ((CrestronEnvironment.ProgramCompatibility & eCrestronSeries.Series4) == eCrestronSeries.Series4)
{
- _wsClient2.Log.Level = (LogLevel) 99999;
+ _wsClient2.Log.Level = (LogLevel)99999;
}
else if ((CrestronEnvironment.ProgramCompatibility & eCrestronSeries.Series3) == eCrestronSeries.Series3)
{
_wsClient2.Log.Level = _wsLogLevel;
}
- //_wsClient2.Log.Level = _wsLogLevel;
-
//This version of the websocket client is TLS1.2 ONLY
//Fires OnMessage event when PING is received.
@@ -1007,9 +1315,9 @@ private void HandleOpen(object sender, EventArgs e)
StopServerReconnectTimer();
StartPingTimer();
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Mobile Control API connected");
- SendMessageObject(new
+ SendMessageObject(new MobileControlMessage
{
- type = "hello"
+ Type = "hello"
});
}
@@ -1073,14 +1381,23 @@ private void SendInitialMessage()
{
Debug.Console(1, this, "Sending initial join message");
+ var touchPanels = DeviceManager.AllDevices.OfType().Where(tp => !tp.UseDirectServer).Select((tp) =>
+ {
+ return new
+ {
+ touchPanelKey = tp.Key,
+ roomKey = tp.DefaultRoomKey
+ };
+ });
- var msg = new
+ var msg = new MobileControlMessage
{
- type = "join",
- content = new
+ Type = "join",
+ Content = JToken.FromObject(new
{
config = GetConfigWithPluginVersion(),
- }
+ touchPanels
+ })
};
SendMessageObject(msg);
@@ -1122,7 +1439,7 @@ public MobileControlEssentialsConfig GetConfigWithPluginVersion()
/// Sends any object type to server
///
///
- public void SendMessageObject(object o)
+ public void SendMessageObject(IMobileControlMessage o)
{
#if SERIES4
if (Config.EnableApiServer)
@@ -1142,7 +1459,7 @@ public void SendMessageObject(object o)
#if SERIES4
public void SendMessageObjectToDirectClient(object o)
{
- if(Config.DirectServer != null && Config.DirectServer.EnableDirectServer && _directServer != null)
+ if (Config.DirectServer != null && Config.DirectServer.EnableDirectServer && _directServer != null)
{
_transmitToClientsQueue.Enqueue(new MessageToClients(o, _directServer));
}
@@ -1203,8 +1520,6 @@ private void PingTimerCallback(object o)
HandleConnectFailure();
}
-
-
}
///
@@ -1236,9 +1551,9 @@ private void StopServerReconnectTimer()
///
private void HandleHeartBeat(JToken content)
{
- SendMessageObject(new
+ SendMessageObject(new MobileControlMessage
{
- type = "/system/heartbeatAck"
+ Type = "/system/heartbeatAck"
});
var code = content["userCode"];
@@ -1259,12 +1574,12 @@ private void HandleClientJoined(JToken content)
var roomKey = content["roomKey"].Value();
- SendMessageObject(new MobileControlResponseMessage()
- {
- Type = "/system/roomKey",
- ClientId = clientId,
- Content = roomKey
- });
+ SendMessageObject(new MobileControlMessage
+ {
+ Type = "/system/roomKey",
+ ClientId = clientId,
+ Content = roomKey
+ });
}
private void HandleUserCode(JToken content)
@@ -1284,10 +1599,10 @@ private void HandleUserCode(JToken content, Action action)
}
catch
{
- qrChecksum = new JValue(String.Empty);
+ qrChecksum = new JValue(string.Empty);
}
- Debug.Console(1, this, "QR checksum: {0}", qrChecksum == null ? String.Empty : qrChecksum.Value());
+ Debug.Console(1, this, "QR checksum: {0}", qrChecksum == null ? string.Empty : qrChecksum.Value());
if (code == null)
{
@@ -1307,40 +1622,6 @@ private void HandleUserCode(JToken content, Action action)
action(code.Value(), qrChecksum.Value());
}
- ///
- /// Outputs debug info when enabled
- ///
- ///
- ///
- private void CheckHttpDebug(HttpClientResponse r, HTTP_CALLBACK_ERROR e)
- {
- if (!_httpDebugEnabled)
- {
- return;
- }
-
- try
- {
- Debug.Console(0, this, "------ Begin HTTP Debug ---------------------------------------");
- if (r != null)
- {
- Debug.Console(0, this, "HTTP Response URL: {0}", r.ResponseUrl ?? "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);
- }
- }
-
public void HandleClientMessage(string message)
{
_receiveQueue.Enqueue(new ProcessStringMessage(message, ParseStreamRx));
@@ -1349,194 +1630,65 @@ public void HandleClientMessage(string message)
///
///
///
- private void ParseStreamRx(string message)
+ private void ParseStreamRx(string messageText)
{
- if (string.IsNullOrEmpty(message))
+ if (string.IsNullOrEmpty(messageText))
{
return;
}
- if (!message.Contains("/system/heartbeat"))
+ if (!messageText.Contains("/system/heartbeat"))
{
- Debug.Console(2, this, "Message RX: {0}", message);
+ Debug.LogMessage(LogEventLevel.Debug, "Message RX: {messageText}", this, messageText);
}
try
{
- var messageObj = JObject.Parse(message);
-
- var type = messageObj["type"].Value();
+ var message = JsonConvert.DeserializeObject(messageText);
- switch (type)
+ switch (message.Type)
{
case "hello":
SendInitialMessage();
break;
case "/system/heartbeat":
- HandleHeartBeat(messageObj["content"]);
+ HandleHeartBeat(message.Content);
break;
case "/system/userCode":
- HandleUserCode(messageObj["content"]);
+ HandleUserCode(message.Content);
break;
case "/system/clientJoined":
- HandleClientJoined(messageObj["content"]);
+ HandleClientJoined(message.Content);
break;
case "raw":
- {
- var wrapper = messageObj["content"].ToObject();
+ var wrapper = message.Content.ToObject();
DeviceJsonApi.DoDeviceAction(wrapper);
- }
break;
case "close":
Debug.Console(1, this, "Received close message from server.");
break;
default:
- 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();
-
- // Look for a button press event
- if (!string.IsNullOrEmpty(stateString))
- {
- switch (stateString)
- {
- case "true":
- {
- if (!_pushedActions.ContainsKey(type))
- {
- _pushedActions.Add(type, new CTimer(o =>
- {
- var pressAndHoldAction = action as PressAndHoldAction;
- if (pressAndHoldAction != null)
- {
- pressAndHoldAction(false);
- }
- _pushedActions.Remove(type);
- }, null, ButtonHeartbeatInterval));
- }
- // Maybe add an else to reset the timer
- break;
- }
- case "held":
- {
- if (_pushedActions.ContainsKey(type))
- {
- _pushedActions[type].Reset(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)
- {
- var stateString = messageObj["content"]["state"].Value();
+ var handlersKv = _actionDictionary.FirstOrDefault(kv => message.Type.StartsWith(kv.Key));
- if (!string.IsNullOrEmpty(stateString))
- {
- (action as Action)(stateString.ToLower() == "true");
- }
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]["value"].Value());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]["value"].Value());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]["value"].Value());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"]
- .ToObject());
- }
- else if (action is ClientSpecificUpdateRequest)
- {
- var clientId = messageObj["clientId"].ToString();
-
-
- (action as ClientSpecificUpdateRequest).ResponseMethod(clientId);
+ if (handlersKv.Key == null)
+ {
+ Debug.Console(1, this, "-- Warning: Incoming message has no registered handler");
+ break;
+ }
- //if (respObj != null)
- //{
- // respObj.ClientId = clientId;
+ var handlers = handlersKv.Value;
- // SendMessageObject(respObj);
- //}
- }
- else if (action is Action)
- {
- (action as Action)(
- messageObj["content"].ToObject());
- }
- else if (action is Action>)
- {
- (action as Action>)(
- messageObj["content"].ToObject>());
- }
- else if (action is Action>)
- {
- (action as Action>)(
- messageObj["content"].ToObject>());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"].ToObject());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"].ToObject());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"].ToObject());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"].ToObject());
- }
- else if (action is Action)
- {
- (action as Action)(messageObj["content"].ToObject());
- }
- else if (action is UserCodeChanged)
- {
- this.HandleUserCode(messageObj["content"], (action as UserCodeChanged).UpdateUserCode);
- }
- }
- else
+ foreach (var handler in handlers)
{
- Debug.Console(1, this, "-- Warning: Incoming message has no registered handler");
+ Task.Run(() => handler.Action(message.Type, message.ClientId, message.Content));
}
+
break;
}
}
catch (Exception err)
{
- Debug.Console(1, this, "Unable to parse message: {0}", err);
+ Debug.LogMessage(err, "Unable to parse {message}:{exception}", this, messageText, err);
}
}
@@ -1568,16 +1720,16 @@ private void TestHttpRequest(string s)
switch (tokens[0].ToLower())
{
case "get":
- {
- var resp = new HttpClient().Get(url);
- CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
- }
+ {
+ var resp = new HttpClient().Get(url);
+ CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
+ }
break;
case "post":
- {
- var resp = new HttpClient().Post(url, new byte[] {});
- CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
- }
+ {
+ var resp = new HttpClient().Post(url, new byte[] { });
+ CrestronConsole.ConsoleCommandResponse("RESPONSE:\r{0}\r\r", resp);
+ }
break;
default:
CrestronConsole.ConsoleCommandResponse("Only get or post supported\r");
@@ -1603,7 +1755,7 @@ private void PrintTestHttpRequestUsage()
public class ClientSpecificUpdateRequest
{
- public ClientSpecificUpdateRequest(Action action )
+ public ClientSpecificUpdateRequest(Action action)
{
ResponseMethod = action;
}
@@ -1620,20 +1772,4 @@ public UserCodeChanged(Action updateMethod)
UpdateUserCode = updateMethod;
}
}
-
-#if SERIES4
- public class MobileControlResponseMessage: IMobileControlResponseMessage
-#else
- public class MobileControlResponseMessage
-#endif
- {
- [JsonProperty("type")]
- public string Type { get; set; }
-
- [JsonProperty("clientId")]
- public object ClientId { get; set; }
-
- [JsonProperty("content")]
- public object Content { get; set; }
- }
}
\ No newline at end of file
diff --git a/3-series/RoomBridges/MobileControlBridgeBase.cs b/3-series/RoomBridges/MobileControlBridgeBase.cs
index 64db272..60485f7 100644
--- a/3-series/RoomBridges/MobileControlBridgeBase.cs
+++ b/3-series/RoomBridges/MobileControlBridgeBase.cs
@@ -1,10 +1,7 @@
-using System;
-using PepperDash.Essentials.Core;
-
-using PepperDash.Core;
-
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Core;
using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
namespace PepperDash.Essentials
@@ -12,7 +9,7 @@ namespace PepperDash.Essentials
///
///
///
- public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoomBridge
+ public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoomMessenger
{
public event EventHandler UserCodeChanged;
@@ -20,8 +17,11 @@ public abstract class MobileControlBridgeBase : MessengerBase, IMobileControlRoo
public event EventHandler ClientJoined;
- public MobileControlSystemController Parent { get; private set; }
+ public event EventHandler AppUrlChanged;
+
+ public IMobileControl Parent { get; private set; }
+ public string AppUrl { get; private set; }
public string UserCode { get; private set; }
public string QrCodeUrl { get; protected set; }
@@ -39,7 +39,7 @@ protected MobileControlBridgeBase(string key, string messagePath)
{
}
- protected MobileControlBridgeBase(string key, string messagePath, Device device)
+ protected MobileControlBridgeBase(string key, string messagePath, IKeyName device)
: base(key, messagePath, device)
{
}
@@ -49,11 +49,11 @@ protected MobileControlBridgeBase(string key, string messagePath, Device device)
/// as adding actions to parent
///
///
- public virtual void AddParent(MobileControlSystemController parent)
+ public virtual void AddParent(IMobileControl parent)
{
Parent = parent;
- McServerUrl = Parent.Config.ClientAppUrl;
+ McServerUrl = Parent.ClientAppUrl;
RegisterWithAppServer(parent);
}
@@ -87,6 +87,17 @@ public void SetUserCode(string code, string qrChecksum)
SetUserCode(code);
}
+ public virtual void UpdateAppUrl(string url)
+ {
+ AppUrl = url;
+
+ var handler = AppUrlChanged;
+
+ if (handler == null) return;
+
+ handler(this, new EventArgs());
+ }
+
///
/// Empty method in base class. Override this to add functionality
/// when code changes
@@ -95,7 +106,7 @@ protected virtual void UserCodeChange()
{
Debug.Console(1, this, "Server user code changed: {0}", UserCode);
- var qrUrl = string.Format("{0}/api/rooms/{1}/{3}/qr?x={2}", Parent.Host, Parent.SystemUuid, new Random().Next());
+ var qrUrl = string.Format($"{Parent.Host}/api/rooms/{Parent.SystemUuid}/{RoomKey}/qr?x={new Random().Next()}");
QrCodeUrl = qrUrl;
Debug.Console(1, this, "Server user code changed: {0} - {1}", UserCode, qrUrl);
@@ -105,29 +116,17 @@ protected virtual void UserCodeChange()
protected void OnUserCodeChanged()
{
- var handler = UserCodeChanged;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
+ UserCodeChanged?.Invoke(this, new EventArgs());
}
protected void OnUserPromptedForCode()
{
- var handler = UserPromptedForCode;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
+ UserPromptedForCode?.Invoke(this, new EventArgs());
}
protected void OnClientJoined()
{
- var handler = ClientJoined;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
+ ClientJoined?.Invoke(this, new EventArgs());
}
}
}
\ No newline at end of file
diff --git a/3-series/RoomBridges/MobileControlEssentialsRoomBridge.cs b/3-series/RoomBridges/MobileControlEssentialsRoomBridge.cs
index 0add835..4fe7786 100644
--- a/3-series/RoomBridges/MobileControlEssentialsRoomBridge.cs
+++ b/3-series/RoomBridges/MobileControlEssentialsRoomBridge.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Crestron.SimplSharp.Ssh;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.AppServer.Messengers;
@@ -13,12 +12,20 @@
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
using PepperDash.Essentials.Devices.Common.Cameras;
-using PepperDash.Essentials.Devices.Common.SoftCodec;
-using PepperDash.Essentials.Core.Lighting;
-using PepperDash.Essentials.Core.Shades;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
+using PepperDash.Essentials.Devices.Common.Room;
+using IShades = PepperDash.Essentials.Core.Shades.IShades;
+using ShadeBase = PepperDash.Essentials.Devices.Common.Shades.ShadeBase;
+using PepperDash.Essentials.Devices.Common.TouchPanel;
+using Crestron.SimplSharp;
+using Volume = PepperDash.Essentials.Room.MobileControl.Volume;
+using PepperDash.Essentials.Core.CrestronIO;
+using PepperDash.Essentials.Core.Lighting;
+using PepperDash.Essentials.Core.Shades;
+
+
#if SERIES4
using PepperDash.Essentials.AppServer;
#endif
@@ -27,11 +34,10 @@ namespace PepperDash.Essentials
{
public class MobileControlEssentialsRoomBridge : MobileControlBridgeBase
{
+ private List _touchPanelTokens = new List();
public IEssentialsRoom Room { get; private set; }
- public string DefaultRoomKey
- {
- get; private set; }
+ public string DefaultRoomKey { get; private set; }
///
///
///
@@ -45,23 +51,13 @@ public override string RoomKey
get { return Room.Key; }
}
- ///
- ///
- ///
- ///
- public MobileControlEssentialsRoomBridge(EssentialsRoomBase room) :
- this(string.Format("mobileControlBridge-{0}", room.Key), room.Key, room)
- {
- Room = room;
- }
-
public MobileControlEssentialsRoomBridge(IEssentialsRoom room) :
- this(string.Format("mobileControlBridge-{0}", room.Key), room.Key, room as Device)
+ this($"mobileControlBridge-{room.Key}", room.Key, room)
{
Room = room;
}
- public MobileControlEssentialsRoomBridge(string key, string roomKey, Device room) : base(key, string.Format(@"/room/{0}/status", roomKey), room)
+ public MobileControlEssentialsRoomBridge(string key, string roomKey, IEssentialsRoom room) : base(key, $"/room/{room.Key}", room as Device)
{
DefaultRoomKey = roomKey;
@@ -69,7 +65,7 @@ public MobileControlEssentialsRoomBridge(string key, string roomKey, Device room
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
@@ -81,158 +77,202 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
Debug.Console(0, this, "Registering Actions with AppServer");
- appServerController.AddAction(string.Format(@"/room/{0}/promptForCode", Room.Key), new Action(OnUserPromptedForCode));
- appServerController.AddAction(string.Format(@"/room/{0}/clientJoined", Room.Key), new Action(OnClientJoined));
+ AddAction("/promptForCode", (id, content) => OnUserPromptedForCode());
+ AddAction("/clientJoined", (id, content) => OnClientJoined());
- appServerController.AddAction(string.Format(@"/room/{0}/userCode", Room.Key),
- new UserCodeChanged(SetUserCode));
+ AddAction("/touchPanels", (id, content) => OnTouchPanelsUpdated(content));
- // Source Changes and room off
- appServerController.AddAction(string.Format(@"/room/{0}/status", Room.Key), new ClientSpecificUpdateRequest((id) => SendFullStatusForClientId(id, Room)));
+ AddAction($"/userApp", (id, content) => OnUserAppUpdated(content));
- var routeRoom = Room as IRunRouteAction;
- if (routeRoom != null)
- appServerController.AddAction(string.Format(@"/room/{0}/source", Room.Key),
- new Action(c =>
- {
- var sourceListKey = string.Empty;
+ AddAction("/userCode", (id, content) =>
+ {
+ var msg = content.ToObject();
- routeRoom.RunRouteAction(c.SourceListItem, sourceListKey);
+ SetUserCode(msg.UserCode, msg.QrChecksum ?? string.Empty);
+ });
- }));
- var directRouteRoom = Room as IRunDirectRouteAction;
- if (directRouteRoom != null)
+ // Source Changes and room off
+ AddAction("/status", (id, content) =>
{
- appServerController.AddAction(String.Format("/room/{0}/directRoute", Room.Key), new Action((d) => directRouteRoom.RunDirectRoute(d.SourceKey, d.DestinationKey)));
- }
+ SendFullStatusForClientId(id, Room);
+ });
+
+ if (Room is IRunRouteAction routeRoom)
+ AddAction("/source", (id, content) =>
+ {
+ var msg = content.ToObject();
- var defaultRoom = Room as IRunDefaultPresentRoute;
- if (defaultRoom != null)
- appServerController.AddAction(string.Format(@"/room/{0}/defaultsource", Room.Key),
- new Action(() => defaultRoom.RunDefaultPresentRoute()));
+ Debug.Console(2, this, "Received request to route to source: {0} on list: {1}", msg.SourceListItemKey, msg.SourceListKey);
- var volumeRoom = Room as IHasCurrentVolumeControls;
- if (volumeRoom != null)
+ routeRoom.RunRouteAction(msg.SourceListItemKey, msg.SourceListKey);
+ });
+
+ if (Room is IRunDirectRouteAction directRouteRoom)
{
- appServerController.AddAction(string.Format(@"/room/{0}/volumes/master/level", Room.Key), new Action(u =>
+ AddAction("/directRoute", (id, content) =>
{
- var basicVolumeWithFeedback = volumeRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
- if (basicVolumeWithFeedback != null)
- basicVolumeWithFeedback.SetVolume(u);
- }));
- appServerController.AddAction(string.Format(@"/room/{0}/volumes/master/muteToggle", Room.Key), new Action(() =>
- volumeRoom.CurrentVolumeControls.MuteToggle()));
- volumeRoom.CurrentVolumeDeviceChange += Room_CurrentVolumeDeviceChange;
+ var msg = content.ToObject();
- // 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;
- }
+
+ Debug.Console(2, this, $"Running direct route from {msg.SourceKey} to {msg.DestinationKey} with signal type {msg.SignalType}");
+
+ directRouteRoom.RunDirectRoute(msg.SourceKey, msg.DestinationKey, msg.SignalType);
+ });
}
- var sscRoom = Room as IHasCurrentSourceInfoChange;
- if (sscRoom != null)
- sscRoom.CurrentSourceChange += Room_CurrentSingleSourceChange;
- var vcRoom = Room as IHasVideoCodec;
- if (vcRoom != null && vcRoom.VideoCodec != null)
+ if (Room is IRunDefaultPresentRoute defaultRoom)
+ AddAction("/defaultsource", (id, content) => defaultRoom.RunDefaultPresentRoute());
+
+ if (Room is IHasCurrentVolumeControls volumeRoom)
{
- var key = vcRoom.VideoCodec.Key + "-" + appServerController.Key;
+ AddAction("/volumes/master/level", (id, content) =>
+ {
+ var msg = content.ToObject>();
+
+
+ if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
+ basicVolumeWithFeedback.SetVolume(msg.Value);
+ });
+
+ AddAction("/volumes/master/muteToggle", (id, content) => volumeRoom.CurrentVolumeControls.MuteToggle());
- if (!appServerController.CheckForDeviceMessenger(key))
+ AddAction("/volumes/master/muteOn", (id, content) =>
{
- var zr = vcRoom.VideoCodec as PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom;
- if (zr != null)
+ if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
+ basicVolumeWithFeedback.MuteOn();
+ });
+
+ AddAction("/volumes/master/muteOff", (id, content) =>
+ {
+ if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
+ basicVolumeWithFeedback.MuteOff();
+ });
+
+ AddAction("/volumes/master/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) =>
{
- var zrMessenger = new ZoomRoomMessenger(key, zr, String.Format("/device/{0}", vcRoom.VideoCodec.Key));
- appServerController.AddDeviceMessenger(zrMessenger);
+ if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
+ {
+ basicVolumeWithFeedback.VolumeUp(b);
+ }
}
- else
+ ));
+
+ AddAction("/volumes/master/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) =>
+ {
+ if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback basicVolumeWithFeedback)
{
- var vcMessenger = new VideoCodecBaseMessenger(key, vcRoom.VideoCodec, String.Format("/device/{0}", vcRoom.VideoCodec.Key));
- appServerController.AddDeviceMessenger(vcMessenger);
+ basicVolumeWithFeedback.VolumeDown(b);
}
}
+ ));
- vcRoom.IsSharingFeedback.OutputChange += IsSharingFeedback_OutputChange;
- }
-
- var acRoom = Room as IHasAudioCodec;
- if (acRoom != null && acRoom.AudioCodec != null)
- {
- var key = acRoom.AudioCodec.Key + "-" + appServerController.Key;
+ volumeRoom.CurrentVolumeDeviceChange += Room_CurrentVolumeDeviceChange;
- if (!appServerController.CheckForDeviceMessenger(key))
+ // Registers for initial volume events, if possible
+ if (volumeRoom.CurrentVolumeControls is IBasicVolumeWithFeedback currentVolumeDevice)
{
- var acMessenger = new AudioCodecBaseMessenger(key, acRoom.AudioCodec,
- String.Format("/device/{0}", acRoom.AudioCodec.Key));
- appServerController.AddDeviceMessenger(acMessenger);
+ Debug.Console(2, this, "Registering for volume feedback events");
+
+ currentVolumeDevice.MuteFeedback.OutputChange += MuteFeedback_OutputChange;
+ currentVolumeDevice.VolumeLevelFeedback.OutputChange += VolumeLevelFeedback_OutputChange;
}
}
- var vtcRoom = Room as IEssentialsHuddleVtc1Room;
- if (vtcRoom != null)
+ if (Room is IHasCurrentSourceInfoChange sscRoom)
+ sscRoom.CurrentSourceChange += Room_CurrentSingleSourceChange;
+
+ if (Room is IEssentialsHuddleVtc1Room vtcRoom)
{
if (vtcRoom.ScheduleSource != null)
{
- var key = vtcRoom.Key + "-" + appServerController.Key;
+ var key = vtcRoom.Key + "-" + Key;
- if (!appServerController.CheckForDeviceMessenger(key))
+ if (!AppServerController.CheckForDeviceMessenger(key))
{
var scheduleMessenger = new IHasScheduleAwarenessMessenger(key, vtcRoom.ScheduleSource,
- string.Format("/room/{0}/schedule", vtcRoom.Key));
- appServerController.AddDeviceMessenger(scheduleMessenger);
+ $"/room/{vtcRoom.Key}");
+ AppServerController.AddDeviceMessenger(scheduleMessenger);
}
}
vtcRoom.InCallFeedback.OutputChange += InCallFeedback_OutputChange;
}
- var privacyRoom = Room as IPrivacy;
- if (privacyRoom != null)
+ if (Room is IPrivacy privacyRoom)
{
- appServerController.AddAction(string.Format(@"/room/{0}/volumes/master/privacyMuteToggle", Room.Key), new Action(privacyRoom.PrivacyModeToggle));
+ AddAction("/volumes/master/privacyMuteToggle", (id, content) => privacyRoom.PrivacyModeToggle());
privacyRoom.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
}
- SetupDeviceMessengers();
+ //SetupDeviceMessengers();
- var defCallRm = Room as IRunDefaultCallRoute;
- if (defCallRm != null)
+ if (Room is IRunDefaultCallRoute defCallRm)
{
- appServerController.AddAction(string.Format(@"/room/{0}/activityVideo", Room.Key),
- new Action(() => defCallRm.RunDefaultCallRoute()));
+ AddAction("/activityVideo", (id, content) => defCallRm.RunDefaultCallRoute());
}
- appServerController.AddAction(string.Format(@"/room/{0}/shutdownStart", Room.Key),
- new Action(() => Room.StartShutdown(eShutdownType.Manual)));
- appServerController.AddAction(string.Format(@"/room/{0}/shutdownEnd", Room.Key),
- new Action(() => Room.ShutdownPromptTimer.Finish()));
- appServerController.AddAction(string.Format(@"/room/{0}/shutdownCancel", Room.Key),
- new Action(() => Room.ShutdownPromptTimer.Cancel()));
+ //AddAction("/shutdownStart", (id, content) => Room.StartShutdown(eShutdownType.Manual));
+
+ //AddAction("/shutdownEnd", (id, content) => Room.ShutdownPromptTimer.Finish());
+
+ //AddAction("/shutdownCancel", (id, content) => 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;
+ //Room.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
+ //Room.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
+ //Room.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
AddTechRoomActions();
}
- private void InCallFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ private void OnTouchPanelsUpdated(JToken content)
{
- var state = new RoomStateMessage();
+ var message = content.ToObject();
+
+ _touchPanelTokens = message.TouchPanels;
+
+ UpdateTouchPanelAppUrls(message.UserAppUrl);
+ }
+
+ private void UpdateTouchPanelAppUrls(string userAppUrl)
+ {
+ foreach (var tp in _touchPanelTokens)
+ {
+ var dev = DeviceManager.AllDevices.OfType().FirstOrDefault((tpc) => tpc.Key.Equals(tp.TouchpanelKey, StringComparison.InvariantCultureIgnoreCase));
+
+ if (dev == null)
+ {
+ continue;
+ }
+
+ //UpdateAppUrl($"{userAppUrl}?token={tp.Token}");
+
+ dev.SetAppUrl($"{userAppUrl}?token={tp.Token}");
+ }
+ }
+
+ private void OnUserAppUpdated(JToken content)
+ {
+ var message = content.ToObject();
+
+ Debug.LogMessage(Serilog.Events.LogEventLevel.Information, "Updating User App URL to {userAppUrl}. Full Message: {@message}", this, message.UserAppUrl, content);
- state.IsInCall = e.BoolValue;
+ UpdateTouchPanelAppUrls(message.UserAppUrl);
+ }
+
+ private void InCallFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ var state = new RoomStateMessage
+ {
+ IsInCall = e.BoolValue
+ };
PostStatusMessage(state);
}
@@ -244,9 +284,8 @@ private void GetRoom()
return;
}
- var tempRoom = DeviceManager.GetDeviceForKey(DefaultRoomKey) as IEssentialsRoom;
- if (tempRoom == null)
+ if (!(DeviceManager.GetDeviceForKey(DefaultRoomKey) is IEssentialsRoom tempRoom))
{
Debug.Console(0, this, "Room with key {0} not found or is not an Essentials Room", DefaultRoomKey);
return;
@@ -267,212 +306,43 @@ protected override void UserCodeChange()
OnUserCodeChanged();
}
- ///
- /// Override of base: calls base to add parent and then registers actions and events.
- ///
- ///
- public override void AddParent(MobileControlSystemController parent)
- {
- base.AddParent(parent);
+ /* ///
+ /// Override of base: calls base to add parent and then registers actions and events.
+ ///
+ ///
+ public override void AddParent(MobileControlSystemController parent)
+ {
+ base.AddParent(parent);
- }
+ }*/
private void AddTechRoomActions()
{
- var techRoom = Room as EssentialsTechRoom;
-
- if (techRoom == null)
+ if (!(Room is IEssentialsTechRoom techRoom))
{
return;
}
- SetTunerActions(techRoom);
-
- CreateScheduleMessenger(techRoom);
-
- Parent.AddAction(String.Format("/room/{0}/roomPowerOn",techRoom.Key), new Action(techRoom.RoomPowerOn));
- Parent.AddAction(String.Format("/room/{0}/roomPowerOff", techRoom.Key), new Action(techRoom.RoomPowerOff));
+ AddAction("/roomPowerOn", (id, content) => techRoom.RoomPowerOn());
+ AddAction("/roomPowerOff", (id, content) => techRoom.RoomPowerOff());
}
- private void CreateScheduleMessenger(EssentialsTechRoom techRoom)
- {
- var scheduleMessenger = new RoomEventScheduleMessenger(techRoom.Key + "-schedule",
- String.Format("/room/{0}/schedule", techRoom.Key), techRoom);
- Parent.AddDeviceMessenger(scheduleMessenger);
- }
-
- private void SetTunerActions(EssentialsTechRoom techRoom)
- {
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
-
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
-
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
-
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
-
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
-
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
-
- foreach (var tuner in techRoom.Tuners.Select(t => t.Value).Cast())
- {
- var stb = tuner;
- stb.LinkActions(Parent);
- }
- }
-
- void PrivacyModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ private void PrivacyModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
var state = new RoomStateMessage();
- var volumes = new Volumes();
-
- volumes.Master = new Volume("master");
- volumes.Master.PrivacyMuted = e.BoolValue;
-
- state.Volumes = volumes;
-
- PostStatusMessage(state);
- }
-
- ///
- /// Set up the messengers for each device type
- ///
- private void SetupDeviceMessengers()
- {
- foreach (var device in DeviceManager.AllDevices)
+ var volumes = new Dictionary
{
- Debug.Console(2, this, "Attempting to set up device messenger for device: {0}", device.Key);
-
- if (device is CameraBase)
- {
- var camDevice = device as CameraBase;
- Debug.Console(2, this, "Adding CameraBaseMessenger for device: {0}", device.Key);
- var cameraMessenger = new CameraBaseMessenger(device.Key + "-" + Parent.Key, camDevice,
- "/device/" + device.Key);
- Parent.AddDeviceMessenger(cameraMessenger);
-
- }
-
- if (device is BlueJeansPc)
- {
- var softCodecDevice = device as BlueJeansPc;
- Debug.Console(2, this, "Adding IRunRouteActionMessnger for device: {0}", device.Key);
- var routeMessenger = new RunRouteActionMessenger(device.Key + "-" + Parent.Key, softCodecDevice,
- "/device/" + device.Key);
- Parent.AddDeviceMessenger(routeMessenger);
-
- }
-
- if (device is ITvPresetsProvider)
- {
- var presetsDevice = device as ITvPresetsProvider;
- if (presetsDevice.TvPresets == null)
- {
- Debug.Console(0, this, "TvPresets is null for device: '{0}'. Skipping DevicePresetsModelMessenger", device.Key);
- }
- else
+ { "master", new Volume("master")
{
- Debug.Console(2, this, "Adding ITvPresetsProvider for device: {0}", device.Key);
- var presetsMessenger = new DevicePresetsModelMessenger(device.Key + "-" + Parent.Key, String.Format("/device/{0}/presets", device.Key),
- presetsDevice);
- Parent.AddDeviceMessenger(presetsMessenger);
-
- }
- }
-
- if (device is DisplayBase)
- {
- var display = device as DisplayBase;
- Debug.Console(2, this, "Adding actions for device: {0}", device.Key);
-
- display.LinkActions(Parent);
+ PrivacyMuted = e.BoolValue
+ }
}
+ };
- if (device is TwoWayDisplayBase)
- {
- var display = device as TwoWayDisplayBase;
- Debug.Console(2, this, "Adding TwoWayDisplayBase for device: {0}", device.Key);
- var twoWayDisplayMessenger = new TwoWayDisplayBaseMessenger(device.Key + "-" + Parent.Key,
- String.Format("/device/{0}", device.Key), display);
- Parent.AddDeviceMessenger(twoWayDisplayMessenger);
- }
-
- if (device is ICommunicationMonitor)
- {
- var monitor = device as ICommunicationMonitor;
- Debug.Console(2, this, "Adding CommunicationMonitor for device: {0}", device.Key);
- var communicationMonitorMessenger = new CommMonitorMessenger(device.Key + "-" + Parent.Key + "-monitor",
- String.Format("/device/{0}/commMonitor", device.Key), monitor);
- Parent.AddDeviceMessenger(communicationMonitorMessenger);
-
- }
-
- if (device is IBasicVolumeWithFeedback)
- {
- var deviceKey = device.Key;
- var volControlDevice = device as IBasicVolumeWithFeedback;
- Debug.Console(2, this, "Adding IBasicVolumeControlWithFeedback for device: {0}", deviceKey);
- var messenger = new DeviceVolumeMessenger(deviceKey + "-" + Parent.Key + "-volume",
- String.Format("/device/{0}/volume", deviceKey), deviceKey, volControlDevice);
- Parent.AddDeviceMessenger(messenger);
- }
-
- if (device is LightingBase)
- {
- var deviceKey = device.Key;
- var lightingDevice = device as LightingBase;
- Debug.Console(2, this, "Adding LightingBaseMessenger for device: {0}", deviceKey);
- var messenger = new LightingBaseMessenger(deviceKey + "-" + Parent.Key,
- lightingDevice, string.Format("/device/{0}", deviceKey));
- Parent.AddDeviceMessenger(messenger);
- }
-
- if (device is ShadeBase)
- {
- var deviceKey = device.Key;
- var shadeDevice = device as ShadeBase;
- Debug.Console(2, this, "Adding ShadeBaseMessenger for device: {0}", deviceKey);
- var messenger = new ShadeBaseMessenger(deviceKey + "-" + Parent.Key,
- shadeDevice, string.Format("/device/{0}", deviceKey));
- Parent.AddDeviceMessenger(messenger);
- }
-
- var genericDevice = device as EssentialsDevice;
-
- if(genericDevice == null)
- {
- continue;
- }
+ state.Volumes = volumes;
- Debug.Console(2, this, "Adding GenericMessenger for device: {0}", genericDevice.Key);
- Parent.AddDeviceMessenger(new GenericMessenger(genericDevice.Key + "-" + Parent.Key + "-generic", genericDevice, string.Format("/device/{0}", genericDevice.Key)));
- }
+ PostStatusMessage(state);
}
///
@@ -486,10 +356,7 @@ private void IsSharingFeedback_OutputChange(object sender, FeedbackEventArgs e)
string shareText;
bool isSharing;
- var vcRoom = Room as IHasVideoCodec;
- var srcInfoRoom = Room as IHasCurrentSourceInfoChange;
-
- if (srcInfoRoom != null && (vcRoom != null && (vcRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && srcInfoRoom.CurrentSourceInfo != null)))
+ if (Room is IHasCurrentSourceInfoChange srcInfoRoom && (Room is IHasVideoCodec vcRoom && (vcRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && srcInfoRoom.CurrentSourceInfo != null)))
{
shareText = srcInfoRoom.CurrentSourceInfo.PreferredName;
isSharing = true;
@@ -500,56 +367,59 @@ private void IsSharingFeedback_OutputChange(object sender, FeedbackEventArgs e)
isSharing = false;
}
- var state = new RoomStateMessage();
-
- state.Share = new ShareState();
- state.Share.CurrentShareText = shareText;
- state.Share.IsSharing = isSharing;
+ var state = new RoomStateMessage
+ {
+ Share = new ShareState
+ {
+ CurrentShareText = shareText,
+ IsSharing = isSharing
+ }
+ };
PostStatusMessage(state);
}
- ///
- /// Handler for cancelled shutdown
- ///
- ///
- ///
- private void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
- {
- var roomStatus = new JObject {{"state", "wasCancelled"}};
- var message = new JObject {{"type", String.Format("/room/{0}/shutdown/", Room.Key)}, {"content", roomStatus}};
- Parent.SendMessageObject(message);
- }
-
- ///
- /// Handler for when shutdown finishes
- ///
- ///
- ///
- private void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
- {
- var roomStatus = new JObject {{"state", "hasFinished"}};
- var message = new JObject { { "type", String.Format("/room/{0}/shutdown/", Room.Key) }, { "content", roomStatus } };
- Parent.SendMessageObject(message);
- }
-
- ///
- /// Handler for when shutdown starts
- ///
- ///
- ///
- private void ShutdownPromptTimer_HasStarted(object sender, EventArgs e)
- {
- var roomStatus = new JObject
- {
- {"state", "hasStarted"},
- {"duration", Room.ShutdownPromptTimer.SecondsToCount}
- };
- var message = new JObject {{"type", String.Format("/room/{0}/shutdown/", Room.Key)}, {"content", roomStatus}};
- Parent.SendMessageObject(message);
- // equivalent JS message:
- // Post( { type: '/room/status/', content: { shutdown: 'hasStarted', duration: Room.ShutdownPromptTimer.SecondsToCount })
- }
+ /////
+ ///// Handler for cancelled shutdown
+ /////
+ /////
+ /////
+ //private void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
+ //{
+ // var roomStatus = new {state = "wasCancelled" };
+
+ // PostStatusMessage(JToken.FromObject(roomStatus));
+ //}
+
+ /////
+ ///// Handler for when shutdown finishes
+ /////
+ /////
+ /////
+ //private void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
+ //{
+ // var roomStatus = new { state= "hasFinished" };
+
+ // PostStatusMessage(JToken.FromObject(roomStatus));
+ //}
+
+ /////
+ ///// Handler for when shutdown starts
+ /////
+ /////
+ /////
+ //private void ShutdownPromptTimer_HasStarted(object sender, EventArgs e)
+ //{
+ // var roomStatus = new
+ // {
+ // state = "hasStarted",
+ // duration = Room.ShutdownPromptTimer.SecondsToCount
+ // };
+
+ // PostStatusMessage(JToken.FromObject(roomStatus));
+ // // equivalent JS message:
+ // // Post( { type: '/room/status/', content: { shutdown: 'hasStarted', duration: Room.ShutdownPromptTimer.SecondsToCount })
+ //}
///
///
@@ -558,10 +428,12 @@ private void ShutdownPromptTimer_HasStarted(object sender, EventArgs e)
///
private void IsWarmingUpFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
- var state = new RoomStateMessage();
+ var state = new
+ {
+ isWarmingUp = e.BoolValue
+ };
- state.IsWarmingUp = e.BoolValue;
- PostStatusMessage(state);
+ PostStatusMessage(JToken.FromObject(state));
}
///
@@ -571,10 +443,11 @@ private void IsWarmingUpFeedback_OutputChange(object sender, FeedbackEventArgs e
///
private void IsCoolingDownFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
- var state = new RoomStateMessage();
-
- state.IsCoolingDown = e.BoolValue;
- PostStatusMessage(state);
+ var state = new
+ {
+ isCoolingDown = e.BoolValue
+ };
+ PostStatusMessage(JToken.FromObject(state));
}
///
@@ -584,10 +457,11 @@ private void IsCoolingDownFeedback_OutputChange(object sender, FeedbackEventArgs
///
private void OnFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
- var state = new RoomStateMessage();
-
- state.IsOn = e.BoolValue;
- PostStatusMessage(state);
+ var state = new
+ {
+ isOn = e.BoolValue
+ };
+ PostStatusMessage(JToken.FromObject(state));
}
private void Room_CurrentVolumeDeviceChange(object sender, VolumeDeviceChangeEventArgs e)
@@ -614,9 +488,10 @@ private void MuteFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
var state = new RoomStateMessage();
- var volumes = new Volumes();
-
- volumes.Master = new Volume("master", e.BoolValue);
+ var volumes = new Dictionary
+ {
+ { "master", new Volume("master", e.BoolValue) }
+ };
state.Volumes = volumes;
@@ -628,15 +503,15 @@ private void MuteFeedback_OutputChange(object sender, FeedbackEventArgs e)
///
private void VolumeLevelFeedback_OutputChange(object sender, FeedbackEventArgs e)
{
- var state = new RoomStateMessage();
-
- var volumes = new Volumes();
-
- volumes.Master = new Volume("master", e.IntValue);
- state.Volumes = volumes;
-
- PostStatusMessage(state);
+ var state = new
+ {
+ volumes = new Dictionary
+ {
+ { "master", new Volume("master", e.IntValue) }
+ }
+ };
+ PostStatusMessage(JToken.FromObject(state));
}
@@ -650,67 +525,7 @@ private void Room_CurrentSingleSourceChange(SourceListItem info, ChangeType type
}
}
*/
- 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 IHasPowerControl)
- (previousDev as IHasPowerControl).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 IHasPowerControl)
- (dev as IHasPowerControl).LinkActions(Parent);
- if (dev is ITransport)
- (dev as ITransport).LinkActions(Parent);
-
- var srcRm = Room as IHasCurrentSourceInfoChange;
- if (srcRm != null)
- {
- var state = new RoomStateMessage();
-
- state.SelectedSourceKey = srcRm.CurrentSourceInfoKey;
- PostStatusMessage(state);
- }
- }
- }
+
}
///
@@ -720,7 +535,8 @@ private void Room_CurrentSingleSourceChange(SourceListItem info, ChangeType type
private void SendFullStatusForClientId(string id, IEssentialsRoom room)
{
//Parent.SendMessageObject(GetFullStatus(room));
- PostStatusMessage(GetFullStatusForClientId(id, room));
+ var message = GetFullStatusForClientId(room);
+ PostStatusMessage(message, id);
}
@@ -729,54 +545,46 @@ private void SendFullStatusForClientId(string id, IEssentialsRoom room)
///
/// The room to get status of
/// The status response message
- MobileControlResponseMessage GetFullStatusForClientId(string id, IEssentialsRoom room)
+ private RoomStateMessage GetFullStatusForClientId(IEssentialsRoom room)
{
Debug.Console(2, this, "GetFullStatus");
var sourceKey = room is IHasCurrentSourceInfoChange ? (room as IHasCurrentSourceInfoChange).CurrentSourceInfoKey : null;
- var rmVc = room as IHasCurrentVolumeControls;
- var volumes = new Volumes();
- if (rmVc != null)
+ var volumes = new Dictionary();
+ if (room is IHasCurrentVolumeControls rmVc)
{
- var vc = rmVc.CurrentVolumeControls as IBasicVolumeWithFeedback;
- if (vc != null)
+ if (rmVc.CurrentVolumeControls is IBasicVolumeWithFeedback vc)
{
- volumes.Master = new Volume("master", vc.VolumeLevelFeedback.UShortValue, vc.MuteFeedback.BoolValue, "Volume", true, "");
-
- var privacyRoom = room as IPrivacy;
- if (privacyRoom != null)
+ var volume = new Volume("master", vc.VolumeLevelFeedback.UShortValue, vc.MuteFeedback.BoolValue, "Volume", true, "");
+ if (room is IPrivacy privacyRoom)
{
- volumes.Master.HasPrivacyMute = true;
- volumes.Master.PrivacyMuted = privacyRoom.PrivacyModeIsOnFeedback.BoolValue;
+ volume.HasPrivacyMute = true;
+ volume.PrivacyMuted = privacyRoom.PrivacyModeIsOnFeedback.BoolValue;
}
+
+ volumes.Add("master", volume);
+
}
}
- var state = new RoomStateMessage();
-
- state.Configuration = GetRoomConfiguration(room);
- state.ActivityMode = 1;
- state.IsOn = room.OnFeedback.BoolValue;
- state.SelectedSourceKey = sourceKey;
- state.Volumes = volumes;
- state.IsWarmingUp = room.IsWarmingUpFeedback.BoolValue;
- state.IsCoolingDown = room.IsCoolingDownFeedback.BoolValue;
+ var state = new RoomStateMessage
+ {
+ Configuration = GetRoomConfiguration(room),
+ ActivityMode = 1,
+ IsOn = room.OnFeedback.BoolValue,
+ SelectedSourceKey = sourceKey,
+ Volumes = volumes,
+ IsWarmingUp = room.IsWarmingUpFeedback.BoolValue,
+ IsCoolingDown = room.IsCoolingDownFeedback.BoolValue
+ };
- var vtcRoom = room as IEssentialsHuddleVtc1Room;
- if (vtcRoom != null)
+ if (room is IEssentialsHuddleVtc1Room vtcRoom)
{
state.IsInCall = vtcRoom.InCallFeedback.BoolValue;
}
- var messageObject = new MobileControlResponseMessage
- {
- Type = MessagePath,
- ClientId = id,
- Content = state
- };
-
- return messageObject;
+ return state;
}
///
@@ -785,108 +593,165 @@ MobileControlResponseMessage GetFullStatusForClientId(string id, IEssentialsRoom
///
private RoomConfiguration GetRoomConfiguration(IEssentialsRoom room)
{
- var configuration = new RoomConfiguration();
+ var configuration = new RoomConfiguration
+ {
+ //ShutdownPromptSeconds = room.ShutdownPromptSeconds,
+ TouchpanelKeys = DeviceManager.AllDevices.
+ OfType()
+ .Where((tp) => tp.DefaultRoomKey.Equals(room.Key, StringComparison.InvariantCultureIgnoreCase))
+ .Select(tp => tp.Key).ToList()
+ };
+
+
+ try
+ {
+ var zrcTp = DeviceManager.AllDevices.OfType().SingleOrDefault((tp) => tp.ZoomRoomController);
+
+ configuration.ZoomRoomControllerKey = zrcTp != null ? zrcTp.Key : room.Key;
+ }
+ catch
+ {
+ configuration.ZoomRoomControllerKey = room.Key;
+ }
+
+ if (room is IEssentialsRoomPropertiesConfig propertiesConfig)
+ {
+ configuration.HelpMessage = propertiesConfig.PropertiesConfig.HelpMessageForDisplay;
+ }
- var huddleRoom = room as IEssentialsHuddleSpaceRoom;
- if (huddleRoom != null && !string.IsNullOrEmpty(huddleRoom.PropertiesConfig.HelpMessageForDisplay))
+ if (room is IEssentialsHuddleSpaceRoom huddleRoom && !string.IsNullOrEmpty(huddleRoom.PropertiesConfig.HelpMessageForDisplay))
{
+ Debug.Console(2, this, "Getting huddle room config");
configuration.HelpMessage = huddleRoom.PropertiesConfig.HelpMessageForDisplay;
configuration.UiBehavior = huddleRoom.PropertiesConfig.UiBehavior;
configuration.DefaultPresentationSourceKey = huddleRoom.PropertiesConfig.DefaultSourceItem;
}
- var vtc1Room = room as IEssentialsHuddleVtc1Room;
- if (vtc1Room != null && !string.IsNullOrEmpty(vtc1Room.PropertiesConfig.HelpMessageForDisplay))
+ if (room is IEssentialsHuddleVtc1Room vtc1Room && !string.IsNullOrEmpty(vtc1Room.PropertiesConfig.HelpMessageForDisplay))
{
+ Debug.Console(2, this, "Getting vtc room config");
configuration.HelpMessage = vtc1Room.PropertiesConfig.HelpMessageForDisplay;
configuration.UiBehavior = vtc1Room.PropertiesConfig.UiBehavior;
configuration.DefaultPresentationSourceKey = vtc1Room.PropertiesConfig.DefaultSourceItem;
}
- var techRoom = room as EssentialsTechRoom;
- if (techRoom != null && !string.IsNullOrEmpty(techRoom.PropertiesConfig.HelpMessage))
+ if (room is IEssentialsTechRoom techRoom && !string.IsNullOrEmpty(techRoom.PropertiesConfig.HelpMessage))
{
+ Debug.Console(2, this, "Getting tech room config");
configuration.HelpMessage = techRoom.PropertiesConfig.HelpMessage;
}
- var vcRoom = room as IHasVideoCodec;
- if (vcRoom != null)
+ if (room is IHasVideoCodec vcRoom)
{
if (vcRoom.VideoCodec != null)
{
+ Debug.Console(2, this, "Getting codec config");
+ var type = vcRoom.VideoCodec.GetType();
+
configuration.HasVideoConferencing = true;
configuration.VideoCodecKey = vcRoom.VideoCodec.Key;
- configuration.VideoCodecIsZoomRoom = vcRoom.VideoCodec is Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom;
+ configuration.VideoCodecIsZoomRoom = type.Name.Equals("ZoomRoom", StringComparison.InvariantCultureIgnoreCase);
}
};
- var acRoom = room as IHasAudioCodec;
- if (acRoom != null)
+ if (room is IHasAudioCodec acRoom)
{
if (acRoom.AudioCodec != null)
{
+ Debug.Console(2, this, "Getting audio codec config");
configuration.HasAudioConferencing = true;
configuration.AudioCodecKey = acRoom.AudioCodec.Key;
}
}
- var envRoom = room as IEnvironmentalControls;
+
+ if (room is IHasMatrixRouting matrixRoutingRoom)
+ {
+ Debug.Console(2, this, "Getting matrix routing config");
+ configuration.MatrixRoutingKey = matrixRoutingRoom.MatrixRoutingDeviceKey;
+ configuration.EndpointKeys = matrixRoutingRoom.EndpointKeys;
+ }
+
+ if (room is IEnvironmentalControls envRoom)
{
+ Debug.Console(2, this, "Getting environmental controls config. RoomHasEnvironmentalControls: {0}", envRoom.HasEnvironmentalControlDevices);
configuration.HasEnvironmentalControls = envRoom.HasEnvironmentalControlDevices;
- if(envRoom.HasEnvironmentalControlDevices)
+ if (envRoom.HasEnvironmentalControlDevices)
{
+ Debug.Console(2, this, "Room Has {0} Environmental Control Devices.", envRoom.EnvironmentalControlDevices.Count);
+
foreach (var dev in envRoom.EnvironmentalControlDevices)
{
+ Debug.Console(2, this, "Adding environmental device: {0}", dev.Key);
+
eEnvironmentalDeviceTypes type = eEnvironmentalDeviceTypes.None;
- if(dev is Essentials.Core.Lighting.LightingBase)
+ if (dev is ILightingScenes || dev is Devices.Common.Lighting.LightingBase)
{
type = eEnvironmentalDeviceTypes.Lighting;
}
- else if (dev is Essentials.Core.Shades.ShadeBase)
+ else if (dev is ShadeBase || dev is IShadesOpenCloseStop || dev is IShadesOpenClosePreset)
{
type = eEnvironmentalDeviceTypes.Shade;
}
- else if (dev is Essentials.Core.Shades.ShadeController)
+ else if (dev is IShades)
{
type = eEnvironmentalDeviceTypes.ShadeController;
}
+ else if (dev is ISwitchedOutput)
+ {
+ type = eEnvironmentalDeviceTypes.Relay;
+ }
+
+ Debug.Console(2, this, "Environmental Device Type: {0}", type);
var envDevice = new EnvironmentalDeviceConfiguration(dev.Key, type);
configuration.EnvironmentalDevices.Add(envDevice);
}
}
+ else
+ {
+ Debug.Console(2, this, "**************************** Room Has No Environmental Control Devices");
+ }
}
- var defDisplayRoom = room as IHasDefaultDisplay;
- if (defDisplayRoom != null)
+ if (room is IHasDefaultDisplay defDisplayRoom)
{
+ Debug.Console(2, this, "Getting default display config");
configuration.DefaultDisplayKey = defDisplayRoom.DefaultDisplay.Key;
- configuration.DisplayKeys.Add(defDisplayRoom.DefaultDisplay.Key);
+ configuration.Destinations.Add(eSourceListItemDestinationTypes.defaultDisplay, defDisplayRoom.DefaultDisplay.Key);
}
- var multiDisplayRoom = room as IHasMultipleDisplays;
- if (multiDisplayRoom != null)
+ if (room is IHasMultipleDisplays multiDisplayRoom)
{
- foreach(var display in multiDisplayRoom.Displays)
+ Debug.Console(2, this, "Getting multiple display config");
+
+ if (multiDisplayRoom.Displays == null)
+ {
+ Debug.Console(2, this, "Displays collection is null");
+ }
+ else
{
- configuration.DisplayKeys.Add(display.Value.Key);
+ Debug.Console(2, this, "Displays collection exists");
+
+ configuration.Destinations = multiDisplayRoom.Displays.ToDictionary(kv => kv.Key, kv => kv.Value.Key);
}
}
var sourceList = ConfigReader.ConfigObject.GetSourceListForKey(room.SourceListKey);
if (sourceList != null)
{
+ Debug.Console(2, this, "Getting source list config");
configuration.SourceList = sourceList;
configuration.HasRoutingControls = true;
foreach (var source in sourceList)
{
- if (source.Value.SourceDevice is PepperDash.Essentials.Devices.Common.IRSetTopBoxBase)
+ if (source.Value.SourceDevice is Devices.Common.IRSetTopBoxBase)
{
configuration.HasSetTopBoxControls = true;
continue;
@@ -899,17 +764,19 @@ private RoomConfiguration GetRoomConfiguration(IEssentialsRoom room)
}
}
- //var cameraDevices = DeviceManager.AllDevices.Where((d) => d is CameraBase);
- //if (cameraDevices != null && cameraDevices.Count() > 0)
- //{
- // configuration.HasCameraControls = true;
- //}
+ var destinationList = ConfigReader.ConfigObject.GetDestinationListForKey(room.DestinationListKey);
+
+ if(destinationList != null)
+ {
+ configuration.DestinationList = destinationList;
+ }
+
return configuration;
}
}
- public class RoomStateMessage: DeviceStateMessageBase
+ public class RoomStateMessage : DeviceStateMessageBase
{
[JsonProperty("configuration", NullValueHandling = NullValueHandling.Ignore)]
public RoomConfiguration Configuration { get; set; }
@@ -928,12 +795,9 @@ public class RoomStateMessage: DeviceStateMessageBase
public string SelectedSourceKey { get; set; }
[JsonProperty("share", NullValueHandling = NullValueHandling.Ignore)]
public ShareState Share { get; set; }
- [JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)]
- public bool? SupportsAdvancedSharing { get; set; }
- [JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)]
- public bool? UserCanChangeShareMode { get; set; }
+
[JsonProperty("volumes", NullValueHandling = NullValueHandling.Ignore)]
- public Volumes Volumes { get; set; }
+ public Dictionary Volumes { get; set; }
[JsonProperty("isInCall", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsInCall { get; set; }
@@ -954,6 +818,9 @@ public class ShareState
///
public class RoomConfiguration
{
+ //[JsonProperty("shutdownPromptSeconds", NullValueHandling = NullValueHandling.Ignore)]
+ //public int? ShutdownPromptSeconds { get; set; }
+
[JsonProperty("hasVideoConferencing", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasVideoConferencing { get; set; }
[JsonProperty("videoCodecIsZoomRoom", NullValueHandling = NullValueHandling.Ignore)]
@@ -969,18 +836,34 @@ public class RoomConfiguration
[JsonProperty("hasRoutingControls", NullValueHandling = NullValueHandling.Ignore)]
public bool? HasRoutingControls { get; set; }
+ [JsonProperty("touchpanelKeys", NullValueHandling = NullValueHandling.Ignore)]
+ public List TouchpanelKeys { get; set; }
+
+ [JsonProperty("zoomRoomControllerKey", NullValueHandling = NullValueHandling.Ignore)]
+ public string ZoomRoomControllerKey { get; set; }
+
+
[JsonProperty("videoCodecKey", NullValueHandling = NullValueHandling.Ignore)]
public string VideoCodecKey { get; set; }
[JsonProperty("audioCodecKey", NullValueHandling = NullValueHandling.Ignore)]
public string AudioCodecKey { get; set; }
+ [JsonProperty("matrixRoutingKey", NullValueHandling = NullValueHandling.Ignore)]
+ public string MatrixRoutingKey { get; set; }
+ [JsonProperty("endpointKeys", NullValueHandling = NullValueHandling.Ignore)]
+ public List EndpointKeys { get; set; }
+
[JsonProperty("defaultDisplayKey", NullValueHandling = NullValueHandling.Ignore)]
public string DefaultDisplayKey { get; set; }
- [JsonProperty("displayKeys", NullValueHandling = NullValueHandling.Ignore)]
- public List DisplayKeys { get; set; }
+ [JsonProperty("destinations", NullValueHandling = NullValueHandling.Ignore)]
+ public Dictionary Destinations { get; set; }
[JsonProperty("environmentalDevices", NullValueHandling = NullValueHandling.Ignore)]
public List EnvironmentalDevices { get; set; }
[JsonProperty("sourceList", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary SourceList { get; set; }
+
+ [JsonProperty("destinationList", NullValueHandling = NullValueHandling.Ignore)]
+ public Dictionary DestinationList { get; set;}
+
[JsonProperty("defaultPresentationSourceKey", NullValueHandling = NullValueHandling.Ignore)]
public string DefaultPresentationSourceKey { get; set; }
@@ -988,14 +871,23 @@ public class RoomConfiguration
[JsonProperty("helpMessage", NullValueHandling = NullValueHandling.Ignore)]
public string HelpMessage { get; set; }
+ [JsonProperty("techPassword", NullValueHandling = NullValueHandling.Ignore)]
+ public string TechPassword { get; set; }
+
[JsonProperty("uiBehavior", NullValueHandling = NullValueHandling.Ignore)]
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
-public RoomConfiguration()
+ [JsonProperty("supportsAdvancedSharing", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? SupportsAdvancedSharing { get; set; }
+ [JsonProperty("userCanChangeShareMode", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? UserCanChangeShareMode { get; set; }
+
+ public RoomConfiguration()
{
- DisplayKeys = new List();
+ Destinations = new Dictionary();
EnvironmentalDevices = new List();
SourceList = new Dictionary();
+ TouchpanelKeys = new List();
}
}
@@ -1022,6 +914,16 @@ public enum eEnvironmentalDeviceTypes
Lighting,
Shade,
ShadeController,
+ Relay,
+ }
+
+ public class ApiTouchPanelToken
+ {
+ [JsonProperty("touchPanels", NullValueHandling = NullValueHandling.Ignore)]
+ public List TouchPanels { get; set; } = new List();
+
+ [JsonProperty("userAppUrl", NullValueHandling = NullValueHandling.Ignore)]
+ public string UserAppUrl { get; set; } = "";
}
#if SERIES3
diff --git a/3-series/RoomBridges/MobileControlSIMPLRoomBridge.cs b/3-series/RoomBridges/MobileControlSIMPLRoomBridge.cs
index 3e78276..a617200 100644
--- a/3-series/RoomBridges/MobileControlSIMPLRoomBridge.cs
+++ b/3-series/RoomBridges/MobileControlSIMPLRoomBridge.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using Crestron.SimplSharp;
+using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.EthernetCommunication;
@@ -11,15 +9,17 @@
using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
-using PepperDash.Essentials.Devices.Common.Codec;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Devices.Common.Cameras;
+using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Room.Config;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
+using System.Collections.Generic;
namespace PepperDash.Essentials.Room.MobileControl
{
-// ReSharper disable once InconsistentNaming
+ // ReSharper disable once InconsistentNaming
public class MobileControlSIMPLRoomBridge : MobileControlBridgeBase, IDelayedConfiguration
{
private const int SupportedDisplayCount = 10;
@@ -70,7 +70,7 @@ public override string RoomKey
///
///
public MobileControlSIMPLRoomBridge(string key, string name, uint ipId)
- : base(key, "/room/room1")
+ : base(key, "")
{
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(ipId, "127.0.0.2", Global.ControlSystem);
var reg = Eisc.Register();
@@ -132,16 +132,16 @@ public override bool CustomActivate()
//SetupFunctions();
//SetupFeedbacks();
- var atcKey = string.Format("atc-{0}-{1}", Key, Parent.Key);
+ var atcKey = string.Format("atc-{0}-{1}", Key, Key);
_atcMessenger = new SIMPLAtcMessenger(atcKey, Eisc, "/device/audioCodec");
_atcMessenger.RegisterWithAppServer(Parent);
- var vtcKey = string.Format("atc-{0}-{1}", Key, Parent.Key);
+ var vtcKey = string.Format("atc-{0}-{1}", Key, Key);
_vtcMessenger = new SIMPLVtcMessenger(vtcKey, Eisc, "/device/videoCodec");
_vtcMessenger.RegisterWithAppServer(Parent);
- var drKey = String.Format("directRoute-{0}-{1}", Key, Parent.Key);
- _directRouteMessenger = new SimplDirectRouteMessenger(drKey, Eisc, "/room/room1/routing");
+ var drKey = string.Format("directRoute-{0}-{1}", Key, Key);
+ _directRouteMessenger = new SimplDirectRouteMessenger(drKey, Eisc, "/routing");
_directRouteMessenger.RegisterWithAppServer(Parent);
CrestronConsole.AddNewConsoleCommand(s =>
@@ -160,7 +160,7 @@ public override bool CustomActivate()
return base.CustomActivate();
}
-
+
private void UseEssentialsConfig()
{
ConfigIsLoaded = false;
@@ -170,17 +170,13 @@ private void UseEssentialsConfig()
Debug.Console(0, this, "******* ESSENTIALS CONFIG: \r{0}",
JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
- var handler = ConfigurationIsReady;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
+ ConfigurationIsReady?.Invoke(this, new EventArgs());
ConfigIsLoaded = true;
}
#if SERIES4
- protected override void CustomRegisterWithAppServer(IMobileControl3 appServerController)
+ protected override void RegisterActions()
#else
protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
#endif
@@ -194,32 +190,38 @@ protected override void CustomRegisterWithAppServer(MobileControlSystemControlle
///
private 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)));
+ AddAction(@"/promptForCode",
+ (id, content) => Eisc.PulseBool(JoinMap.PromptForCode.JoinNumber));
+ AddAction(@"/clientJoined", (id, content) => Eisc.PulseBool(JoinMap.ClientJoined.JoinNumber));
- Parent.AddAction(@"/room/room1/status", new Action(SendFullStatus));
+ AddAction(@"/status", (id, content) => SendFullStatus());
- Parent.AddAction(@"/room/room1/source", new Action(c =>
+ AddAction(@"/source", (id, content) =>
{
- Eisc.SetString(JoinMap.CurrentSourceKey.JoinNumber, c.SourceListItem);
+ var msg = content.ToObject();
+
+ Eisc.SetString(JoinMap.CurrentSourceKey.JoinNumber, msg.SourceListItemKey);
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)));
+ AddAction(@"/defaultsource", (id, content) =>
+ Eisc.PulseBool(JoinMap.ActivityShare.JoinNumber));
+ AddAction(@"/activityPhone", (id, content) =>
+ Eisc.PulseBool(JoinMap.ActivityPhoneCall.JoinNumber));
+ AddAction(@"/activityVideo", (id, content) =>
+ Eisc.PulseBool(JoinMap.ActivityVideoCall.JoinNumber));
- Parent.AddAction(@"/room/room1/volumes/master/level", new Action(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)));
+ AddAction(@"/volumes/master/level", (id, content) =>
+ {
+ var value = content["value"].Value();
+
+ Eisc.SetUshort(JoinMap.MasterVolume.JoinNumber, value);
+ });
+
+ AddAction(@"/volumes/master/muteToggle", (id, content) =>
+ Eisc.PulseBool(JoinMap.MasterVolume.JoinNumber));
+ AddAction(@"/volumes/master/privacyMuteToggle", (id, content) =>
+ Eisc.PulseBool(JoinMap.PrivacyMute.JoinNumber));
// /xyzxyz/volumes/master/muteToggle ---> BoolInput[1]
@@ -230,18 +232,22 @@ private void SetupFunctions()
for (uint i = volumeStart; i <= volumeEnd; i++)
{
var index = i;
- Parent.AddAction(string.Format(@"/room/room1/volumes/level-{0}/level", index), new Action(u =>
- Eisc.SetUshort(index, u)));
- Parent.AddAction(string.Format(@"/room/room1/volumes/level-{0}/muteToggle", index), new Action(() =>
- Eisc.PulseBool(index)));
+ AddAction(string.Format(@"/volumes/level-{0}/level", index), (id, content) =>
+ {
+ var value = content["value"].Value();
+ Eisc.SetUshort(index, value);
+ });
+
+ AddAction(string.Format(@"/volumes/level-{0}/muteToggle", index), (id, content) =>
+ 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)));
+ AddAction(@"/shutdownStart", (id, content) =>
+ Eisc.PulseBool(JoinMap.ShutdownStart.JoinNumber));
+ AddAction(@"/shutdownEnd", (id, content) =>
+ Eisc.PulseBool(JoinMap.ShutdownEnd.JoinNumber));
+ AddAction(@"/shutdownCancel", (id, content) =>
+ Eisc.PulseBool(JoinMap.ShutdownCancel.JoinNumber));
}
@@ -258,11 +264,28 @@ private void SetupSourceFunctions(string 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)));
+ AddAction(string.Format("{0}{1}", prefix, item.Key), (id, content) =>
+ {
+ HandlePressAndHoldEisc(content, b => Eisc.SetBool(join, b));
+ });
}
}
+ private void HandlePressAndHoldEisc(JToken content, Action action)
+ {
+ var state = content.ToObject>();
+
+ var timerHandler = PressAndHoldHandler.GetPressAndHoldHandler(state.Value);
+ if (timerHandler == null)
+ {
+ return;
+ }
+
+ timerHandler(state.Value, action);
+
+ action(state.Value.Equals("true", StringComparison.InvariantCultureIgnoreCase));
+ }
+
///
/// Links feedbacks to whatever is gonna happen!
@@ -331,7 +354,7 @@ private void SetupFeedbacks()
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 {{"level-" + index, new {level = u}}};
+ var dict = new Dictionary { { "level-" + index, new { level = u } } };
PostStatus(new
{
volumes = new
@@ -343,7 +366,7 @@ private void SetupFeedbacks()
Eisc.SetBoolSigAction(index, b =>
{
// need a dict in order to create the level-n property on auxFaders
- var dict = new Dictionary {{"level-" + index, new {muted = b}}};
+ var dict = new Dictionary { { "level-" + index, new { muted = b } } };
PostStatus(new
{
volumes = new
@@ -365,17 +388,17 @@ private void SetupFeedbacks()
// shutdown things
Eisc.SetSigTrueAction(JoinMap.ShutdownCancel.JoinNumber, () =>
- PostMessage("/room/room1/shutdown/", new
+ PostMessage("/shutdown/", new
{
state = "wasCancelled"
}));
Eisc.SetSigTrueAction(JoinMap.ShutdownEnd.JoinNumber, () =>
- PostMessage("/room/room1/shutdown/", new
+ PostMessage("/shutdown/", new
{
state = "hasFinished"
}));
Eisc.SetSigTrueAction(JoinMap.ShutdownStart.JoinNumber, () =>
- PostMessage("/room/room1/shutdown/", new
+ PostMessage("/shutdown/", new
{
state = "hasStarted",
duration = Eisc.UShortOutput[JoinMap.ShutdownPromptDuration.JoinNumber].UShortValue
@@ -389,7 +412,7 @@ private void SetupFeedbacks()
Eisc.SetSigTrueAction(JoinMap.ActivityPhoneCall.JoinNumber, () => UpdateActivity(2));
Eisc.SetSigTrueAction(JoinMap.ActivityVideoCall.JoinNumber, () => UpdateActivity(3));
- Parent.ApiOnlineAndAuthorized.LinkInputSig(Eisc.BooleanInput[JoinMap.ApiOnlineAndAuthorized.JoinNumber]);
+ AppServerController.ApiOnlineAndAuthorized.LinkInputSig(Eisc.BooleanInput[JoinMap.ApiOnlineAndAuthorized.JoinNumber]);
}
@@ -443,9 +466,11 @@ private DeviceConfig GetSyntheticSourceDevice(SourceListItem sli, string type, u
{
if (type.ToLower().Equals("simplcameramessenger"))
{
- var props = new SimplMessengerPropertiesConfig();
- props.DeviceKey = key;
- props.JoinMapKey = "";
+ var props = new SimplMessengerPropertiesConfig
+ {
+ DeviceKey = key,
+ JoinMapKey = ""
+ };
var joinStart = 1000 + (i * 100) + 1; // 1001, 1101, 1201, 1301... etc.
props.JoinStart = joinStart;
devConf.Properties = JToken.FromObject(props);
@@ -465,9 +490,9 @@ private void LoadConfigValues()
var co = ConfigReader.ConfigObject;
- if (!String.IsNullOrEmpty(Eisc.StringOutput[JoinMap.PortalSystemUrl.JoinNumber].StringValue))
+ if (!string.IsNullOrEmpty(Eisc.StringOutput[JoinMap.PortalSystemUrl.JoinNumber].StringValue))
{
- Parent.SystemUrl = Eisc.StringOutput[JoinMap.PortalSystemUrl.JoinNumber].StringValue;
+ ConfigReader.ConfigObject.SystemUrl = Eisc.StringOutput[JoinMap.PortalSystemUrl.JoinNumber].StringValue;
}
co.Info.RuntimeInfo.AppName = Assembly.GetExecutingAssembly().GetName().Name;
@@ -513,7 +538,7 @@ private void LoadConfigValues()
// This MAY need a check
if (Eisc.BooleanOutput[JoinMap.ActivityPhoneCallEnable.JoinNumber].BoolValue)
{
- rmProps.AudioCodecKey = "audioCodec";
+ rmProps.AudioCodecKey = "audioCodec";
}
if (Eisc.BooleanOutput[JoinMap.ActivityVideoCallEnable.JoinNumber].BoolValue)
@@ -573,7 +598,7 @@ private void LoadConfigValues()
Debug.Console(1, "Source at join {0} does not have a name", JoinMap.SourceNameJoinStart.JoinNumber + i);
break;
}
-
+
var icon = Eisc.StringOutput[JoinMap.SourceIconJoinStart.JoinNumber + i].StringValue;
var key = Eisc.StringOutput[JoinMap.SourceKeyJoinStart.JoinNumber + i].StringValue;
@@ -591,7 +616,7 @@ private void LoadConfigValues()
{
Icon = icon,
Name = name,
- Order = (int) i + 10,
+ Order = (int)i + 10,
SourceKey = string.IsNullOrEmpty(sourceKey) ? key : sourceKey, // Use the value from the join if defined
Type = eSourceListItemType.Route,
DisableCodecSharing = disableShare,
@@ -621,7 +646,7 @@ private void LoadConfigValues()
}
}
else
- {
+ {
co.Devices.Add(syntheticDevice);
}
}
@@ -725,16 +750,12 @@ private void LoadConfigValues()
Debug.Console(0, this, "******* CONFIG FROM SIMPL: \r{0}",
JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented));
- var handler = ConfigurationIsReady;
- if (handler != null)
- {
- handler(this, new EventArgs());
- }
+ ConfigurationIsReady?.Invoke(this, new EventArgs());
ConfigIsLoaded = true;
}
- private DeviceConfig GetSyntheticDestinationDevice(DestinationListItem newDli, string key, string name)
+ private DeviceConfig GetSyntheticDestinationDevice(string key, string name)
{
// If not, synthesize the device config
var devConf = new DeviceConfig
@@ -768,7 +789,7 @@ private void CreateDestinationList(BasicConfig co)
continue;
}
- if (String.IsNullOrEmpty(key))
+ if (string.IsNullOrEmpty(key))
{
continue;
}
@@ -778,9 +799,9 @@ private void CreateDestinationList(BasicConfig co)
eRoutingSignalType parsedType;
try
{
- parsedType = (eRoutingSignalType) Enum.Parse(typeof (eRoutingSignalType), routeType, true);
+ parsedType = (eRoutingSignalType)Enum.Parse(typeof(eRoutingSignalType), routeType, true);
}
- catch
+ catch
{
Debug.Console(0, this, "Error parsing destination type: {0}", routeType);
parsedType = eRoutingSignalType.AudioVideo;
@@ -789,7 +810,7 @@ private void CreateDestinationList(BasicConfig co)
var newDli = new DestinationListItem
{
Name = name,
- Order = (int) i,
+ Order = (int)i,
SinkKey = key,
SinkType = parsedType,
};
@@ -815,7 +836,7 @@ private void CreateDestinationList(BasicConfig co)
var existingDev = co.GetDeviceForKey(key);
- var syntheticDisplay = GetSyntheticDestinationDevice(newDli, key, name);
+ var syntheticDisplay = GetSyntheticDestinationDevice(key, name);
if (existingDev != null)
{
@@ -824,7 +845,6 @@ private void CreateDestinationList(BasicConfig co)
if (existingDev.Properties.Value(_syntheticDeviceKey))
{
Debug.Console(0, this, "Updating previous device config with new values");
- existingDev = syntheticDisplay;
}
else
{
@@ -832,7 +852,7 @@ private void CreateDestinationList(BasicConfig co)
}
}
else
- {
+ {
co.Devices.Add(syntheticDisplay);
}
}
@@ -846,7 +866,7 @@ private void CreateDestinationList(BasicConfig co)
co.DestinationLists["default"] = newDl;
}
- _directRouteMessenger.RegisterForDestinationPaths();
+ _directRouteMessenger.RegisterForDestinationPaths();
}
///
@@ -865,7 +885,7 @@ private void SetupDeviceMessengers()
var props =
JsonConvert.DeserializeObject(device.Properties.ToString());
- var messengerKey = string.Format("device-{0}-{1}", Key, Parent.Key);
+ var messengerKey = string.Format("device-{0}-{1}", Key, Key);
if (DeviceManager.GetDeviceForKey(messengerKey) != null)
{
@@ -919,7 +939,7 @@ private void SetupDeviceMessengers()
{
var camDevice = dev as CameraBase;
Debug.Console(1, this, "Adding CameraBaseMessenger for device: {0}", dev.Key);
- var cameraMessenger = new CameraBaseMessenger(device.Key + "-" + Parent.Key, camDevice,
+ var cameraMessenger = new CameraBaseMessenger(device.Key + "-" + Key, camDevice,
"/device/" + device.Key);
DeviceMessengers.Add(device.Key, cameraMessenger);
DeviceManager.AddDevice(cameraMessenger);
@@ -1020,10 +1040,10 @@ private int GetActivityMode()
/// The contents of the content object
private void PostStatus(object contentObject)
{
- Parent.SendMessageObject(new
+ AppServerController.SendMessageObject(new MobileControlMessage
{
- type = "/room/room1/status/",
- content = contentObject
+ Type = "/status/",
+ Content = JToken.FromObject(contentObject)
});
}
@@ -1034,10 +1054,10 @@ private void PostStatus(object contentObject)
///
private void PostMessage(string messageType, object contentObject)
{
- Parent.SendMessageObject(new
+ AppServerController.SendMessageObject(new MobileControlMessage
{
- type = messageType,
- content = contentObject
+ Type = messageType,
+ Content = JToken.FromObject(contentObject)
});
}
@@ -1082,7 +1102,7 @@ private Dictionary GetSourceGroupDictionary()
};
return d;
- }
+ }
///
/// updates the usercode from server
@@ -1092,7 +1112,7 @@ protected override void UserCodeChange()
Debug.Console(1, this, "Server user code changed: {0}", UserCode);
- var qrUrl = string.Format("{0}/api/rooms/{1}/{3}/qr?x={2}", Parent.Host, Parent.SystemUuid, new Random().Next(), "room1" );
+ var qrUrl = string.Format("{0}/api/rooms/{1}/{3}/qr?x={2}", AppServerController.Host, AppServerController.SystemUuid, new Random().Next(), "room1");
QrCodeUrl = qrUrl;
Debug.Console(1, this, "Server user code changed: {0} - {1}", UserCode, qrUrl);
diff --git a/3-series/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs b/3-series/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs
index 5702e1d..fd6e871 100644
--- a/3-series/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs
+++ b/3-series/SIMPLJoinMaps/MobileControlSIMPLRoomJoinMap.cs
@@ -3,11 +3,12 @@
namespace PepperDash.Essentials.AppServer
{
-// ReSharper disable once InconsistentNaming
+ // ReSharper disable once InconsistentNaming
public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
{
- [JoinName("QrCodeUrl")] public JoinDataComplete QrCodeUrl =
- new JoinDataComplete(new JoinData {JoinNumber = 403, JoinSpan = 1},
+ [JoinName("QrCodeUrl")]
+ public JoinDataComplete QrCodeUrl =
+ new JoinDataComplete(new JoinData { JoinNumber = 403, JoinSpan = 1 },
new JoinMetadata
{
Description = "QR Code URL",
@@ -25,8 +26,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("MasterVolume")] public JoinDataComplete MasterVolume =
- new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 1},
+ [JoinName("MasterVolume")]
+ public JoinDataComplete MasterVolume =
+ new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata
{
Description = "Master Volume Mute Toggle/FB/Level/Label",
@@ -34,8 +36,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.DigitalAnalogSerial
});
- [JoinName("VolumeJoinStart")] public JoinDataComplete VolumeJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 2, JoinSpan = 8},
+ [JoinName("VolumeJoinStart")]
+ public JoinDataComplete VolumeJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 8 },
new JoinMetadata
{
Description = "Volume Mute Toggle/FB/Level/Label",
@@ -43,8 +46,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.DigitalAnalogSerial
});
- [JoinName("PrivacyMute")] public JoinDataComplete PrivacyMute =
- new JoinDataComplete(new JoinData {JoinNumber = 12, JoinSpan = 1},
+ [JoinName("PrivacyMute")]
+ public JoinDataComplete PrivacyMute =
+ new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata
{
Description = "Privacy Mute Toggle/FB",
@@ -52,8 +56,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("PromptForCode")] public JoinDataComplete PromptForCode =
- new JoinDataComplete(new JoinData {JoinNumber = 41, JoinSpan = 1},
+ [JoinName("PromptForCode")]
+ public JoinDataComplete PromptForCode =
+ new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 },
new JoinMetadata
{
Description = "Prompt User for Code",
@@ -61,8 +66,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ClientJoined")] public JoinDataComplete ClientJoined =
- new JoinDataComplete(new JoinData {JoinNumber = 42, JoinSpan = 1},
+ [JoinName("ClientJoined")]
+ public JoinDataComplete ClientJoined =
+ new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
new JoinMetadata
{
Description = "Client Joined",
@@ -90,8 +96,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ActivityShare")] public JoinDataComplete ActivityShare =
- new JoinDataComplete(new JoinData {JoinNumber = 51, JoinSpan = 1},
+ [JoinName("ActivityShare")]
+ public JoinDataComplete ActivityShare =
+ new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1 },
new JoinMetadata
{
Description = "Activity Share",
@@ -99,8 +106,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ActivityPhoneCall")] public JoinDataComplete ActivityPhoneCall =
- new JoinDataComplete(new JoinData {JoinNumber = 52, JoinSpan = 1},
+ [JoinName("ActivityPhoneCall")]
+ public JoinDataComplete ActivityPhoneCall =
+ new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1 },
new JoinMetadata
{
Description = "Activity Phone Call",
@@ -108,8 +116,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ActivityVideoCall")] public JoinDataComplete ActivityVideoCall =
- new JoinDataComplete(new JoinData {JoinNumber = 53, JoinSpan = 1},
+ [JoinName("ActivityVideoCall")]
+ public JoinDataComplete ActivityVideoCall =
+ new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1 },
new JoinMetadata
{
Description = "Activity Video Call",
@@ -117,8 +126,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ShutdownPromptDuration")] public JoinDataComplete ShutdownPromptDuration =
- new JoinDataComplete(new JoinData {JoinNumber = 61, JoinSpan = 1},
+ [JoinName("ShutdownPromptDuration")]
+ public JoinDataComplete ShutdownPromptDuration =
+ new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 },
new JoinMetadata
{
Description = "Shutdown Cancel",
@@ -126,8 +136,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Analog
});
- [JoinName("ShutdownCancel")] public JoinDataComplete ShutdownCancel =
- new JoinDataComplete(new JoinData {JoinNumber = 61, JoinSpan = 1},
+ [JoinName("ShutdownCancel")]
+ public JoinDataComplete ShutdownCancel =
+ new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 },
new JoinMetadata
{
Description = "Shutdown Cancel",
@@ -135,8 +146,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ShutdownEnd")] public JoinDataComplete ShutdownEnd =
- new JoinDataComplete(new JoinData {JoinNumber = 62, JoinSpan = 1},
+ [JoinName("ShutdownEnd")]
+ public JoinDataComplete ShutdownEnd =
+ new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 1 },
new JoinMetadata
{
Description = "Shutdown End",
@@ -144,8 +156,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ShutdownStart")] public JoinDataComplete ShutdownStart =
- new JoinDataComplete(new JoinData {JoinNumber = 63, JoinSpan = 1},
+ [JoinName("ShutdownStart")]
+ public JoinDataComplete ShutdownStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 63, JoinSpan = 1 },
new JoinMetadata
{
Description = "Shutdown Start",
@@ -153,8 +166,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("SourceHasChanged")] public JoinDataComplete SourceHasChanged =
- new JoinDataComplete(new JoinData {JoinNumber = 71, JoinSpan = 1},
+ [JoinName("SourceHasChanged")]
+ public JoinDataComplete SourceHasChanged =
+ new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 },
new JoinMetadata
{
Description = "Source Changed",
@@ -162,8 +176,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CurrentSourceKey")] public JoinDataComplete CurrentSourceKey =
- new JoinDataComplete(new JoinData {JoinNumber = 71, JoinSpan = 1},
+ [JoinName("CurrentSourceKey")]
+ public JoinDataComplete CurrentSourceKey =
+ new JoinDataComplete(new JoinData { JoinNumber = 71, JoinSpan = 1 },
new JoinMetadata
{
Description = "Key of selected source",
@@ -172,8 +187,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
});
- [JoinName("ConfigIsLocal")] public JoinDataComplete ConfigIsLocal =
- new JoinDataComplete(new JoinData {JoinNumber = 100, JoinSpan = 1},
+ [JoinName("ConfigIsLocal")]
+ public JoinDataComplete ConfigIsLocal =
+ new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 },
new JoinMetadata
{
Description = "Config is local to Essentials",
@@ -181,8 +197,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("NumberOfAuxFaders")] public JoinDataComplete NumberOfAuxFaders =
- new JoinDataComplete(new JoinData {JoinNumber = 101, JoinSpan = 1},
+ [JoinName("NumberOfAuxFaders")]
+ public JoinDataComplete NumberOfAuxFaders =
+ new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 1 },
new JoinMetadata
{
Description = "Number of Auxilliary Faders",
@@ -190,8 +207,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Analog
});
- [JoinName("SpeedDialNameStartJoin")] public JoinDataComplete SpeedDialNameStartJoin =
- new JoinDataComplete(new JoinData {JoinNumber = 241, JoinSpan = 10},
+ [JoinName("SpeedDialNameStartJoin")]
+ public JoinDataComplete SpeedDialNameStartJoin =
+ new JoinDataComplete(new JoinData { JoinNumber = 241, JoinSpan = 10 },
new JoinMetadata
{
Description = "Speed Dial names",
@@ -199,8 +217,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("SpeedDialNumberStartJoin")] public JoinDataComplete SpeedDialNumberStartJoin =
- new JoinDataComplete(new JoinData {JoinNumber = 251, JoinSpan = 10},
+ [JoinName("SpeedDialNumberStartJoin")]
+ public JoinDataComplete SpeedDialNumberStartJoin =
+ new JoinDataComplete(new JoinData { JoinNumber = 251, JoinSpan = 10 },
new JoinMetadata
{
Description = "Speed Dial numbers",
@@ -208,8 +227,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("SpeedDialVisibleStartJoin")] public JoinDataComplete SpeedDialVisibleStartJoin =
- new JoinDataComplete(new JoinData {JoinNumber = 261, JoinSpan = 10},
+ [JoinName("SpeedDialVisibleStartJoin")]
+ public JoinDataComplete SpeedDialVisibleStartJoin =
+ new JoinDataComplete(new JoinData { JoinNumber = 261, JoinSpan = 10 },
new JoinMetadata
{
Description = "Speed Dial Visible",
@@ -217,8 +237,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("RoomIsOn")] public JoinDataComplete RoomIsOn =
- new JoinDataComplete(new JoinData {JoinNumber = 301, JoinSpan = 1},
+ [JoinName("RoomIsOn")]
+ public JoinDataComplete RoomIsOn =
+ new JoinDataComplete(new JoinData { JoinNumber = 301, JoinSpan = 1 },
new JoinMetadata
{
Description = "Room Is On",
@@ -226,8 +247,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("UserCodeToSystem")] public JoinDataComplete UserCodeToSystem =
- new JoinDataComplete(new JoinData {JoinNumber = 401, JoinSpan = 1},
+ [JoinName("UserCodeToSystem")]
+ public JoinDataComplete UserCodeToSystem =
+ new JoinDataComplete(new JoinData { JoinNumber = 401, JoinSpan = 1 },
new JoinMetadata
{
Description = "User Code",
@@ -235,8 +257,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("ServerUrl")] public JoinDataComplete ServerUrl =
- new JoinDataComplete(new JoinData {JoinNumber = 402, JoinSpan = 1},
+ [JoinName("ServerUrl")]
+ public JoinDataComplete ServerUrl =
+ new JoinDataComplete(new JoinData { JoinNumber = 402, JoinSpan = 1 },
new JoinMetadata
{
Description = "Server URL",
@@ -244,8 +267,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("ConfigRoomName")] public JoinDataComplete ConfigRoomName =
- new JoinDataComplete(new JoinData {JoinNumber = 501, JoinSpan = 1},
+ [JoinName("ConfigRoomName")]
+ public JoinDataComplete ConfigRoomName =
+ new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 1 },
new JoinMetadata
{
Description = "Room Name",
@@ -253,8 +277,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("ConfigHelpMessage")] public JoinDataComplete ConfigHelpMessage =
- new JoinDataComplete(new JoinData {JoinNumber = 502, JoinSpan = 1},
+ [JoinName("ConfigHelpMessage")]
+ public JoinDataComplete ConfigHelpMessage =
+ new JoinDataComplete(new JoinData { JoinNumber = 502, JoinSpan = 1 },
new JoinMetadata
{
Description = "Room help message",
@@ -262,8 +287,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("ConfigHelpNumber")] public JoinDataComplete ConfigHelpNumber =
- new JoinDataComplete(new JoinData {JoinNumber = 503, JoinSpan = 1},
+ [JoinName("ConfigHelpNumber")]
+ public JoinDataComplete ConfigHelpNumber =
+ new JoinDataComplete(new JoinData { JoinNumber = 503, JoinSpan = 1 },
new JoinMetadata
{
Description = "Room help number",
@@ -271,8 +297,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("ConfigRoomPhoneNumber")] public JoinDataComplete ConfigRoomPhoneNumber =
- new JoinDataComplete(new JoinData {JoinNumber = 504, JoinSpan = 1},
+ [JoinName("ConfigRoomPhoneNumber")]
+ public JoinDataComplete ConfigRoomPhoneNumber =
+ new JoinDataComplete(new JoinData { JoinNumber = 504, JoinSpan = 1 },
new JoinMetadata
{
Description = "Room phone number",
@@ -280,8 +307,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("ConfigRoomURI")] public JoinDataComplete ConfigRoomUri =
- new JoinDataComplete(new JoinData {JoinNumber = 505, JoinSpan = 1},
+ [JoinName("ConfigRoomURI")]
+ public JoinDataComplete ConfigRoomUri =
+ new JoinDataComplete(new JoinData { JoinNumber = 505, JoinSpan = 1 },
new JoinMetadata
{
Description = "Room URI",
@@ -299,8 +327,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ConfigIsReady")] public JoinDataComplete ConfigIsReady =
- new JoinDataComplete(new JoinData {JoinNumber = 501, JoinSpan = 1},
+ [JoinName("ConfigIsReady")]
+ public JoinDataComplete ConfigIsReady =
+ new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 1 },
new JoinMetadata
{
Description = "Config info from SIMPL is ready",
@@ -318,8 +347,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("HideVideoConfRecents")] public JoinDataComplete HideVideoConfRecents =
- new JoinDataComplete(new JoinData {JoinNumber = 502, JoinSpan = 1},
+ [JoinName("HideVideoConfRecents")]
+ public JoinDataComplete HideVideoConfRecents =
+ new JoinDataComplete(new JoinData { JoinNumber = 502, JoinSpan = 1 },
new JoinMetadata
{
Description = "Hide Video Conference Recents",
@@ -327,8 +357,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("ShowCameraWhenNotInCall")] public JoinDataComplete ShowCameraWhenNotInCall =
- new JoinDataComplete(new JoinData {JoinNumber = 503, JoinSpan = 1},
+ [JoinName("ShowCameraWhenNotInCall")]
+ public JoinDataComplete ShowCameraWhenNotInCall =
+ new JoinDataComplete(new JoinData { JoinNumber = 503, JoinSpan = 1 },
new JoinMetadata
{
Description = "Show camera when not in call",
@@ -336,8 +367,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("UseSourceEnabled")] public JoinDataComplete UseSourceEnabled =
- new JoinDataComplete(new JoinData {JoinNumber = 504, JoinSpan = 1},
+ [JoinName("UseSourceEnabled")]
+ public JoinDataComplete UseSourceEnabled =
+ new JoinDataComplete(new JoinData { JoinNumber = 504, JoinSpan = 1 },
new JoinMetadata
{
Description = "Use Source Enabled Joins",
@@ -346,8 +378,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
});
- [JoinName("SourceShareDisableJoinStart")] public JoinDataComplete SourceShareDisableJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 601, JoinSpan = 20},
+ [JoinName("SourceShareDisableJoinStart")]
+ public JoinDataComplete SourceShareDisableJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 601, JoinSpan = 20 },
new JoinMetadata
{
Description = "Source is not sharable",
@@ -355,8 +388,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("SourceIsEnabledJoinStart")] public JoinDataComplete SourceIsEnabledJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 621, JoinSpan = 20},
+ [JoinName("SourceIsEnabledJoinStart")]
+ public JoinDataComplete SourceIsEnabledJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 621, JoinSpan = 20 },
new JoinMetadata
{
Description = "Source is enabled/visible",
@@ -385,8 +419,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
});
- [JoinName("SourceNameJoinStart")] public JoinDataComplete SourceNameJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 601, JoinSpan = 20},
+ [JoinName("SourceNameJoinStart")]
+ public JoinDataComplete SourceNameJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 601, JoinSpan = 20 },
new JoinMetadata
{
Description = "Source Names",
@@ -394,8 +429,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("SourceIconJoinStart")] public JoinDataComplete SourceIconJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 621, JoinSpan = 20},
+ [JoinName("SourceIconJoinStart")]
+ public JoinDataComplete SourceIconJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 621, JoinSpan = 20 },
new JoinMetadata
{
Description = "Source Icons",
@@ -403,8 +439,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("SourceKeyJoinStart")] public JoinDataComplete SourceKeyJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 641, JoinSpan = 20},
+ [JoinName("SourceKeyJoinStart")]
+ public JoinDataComplete SourceKeyJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 641, JoinSpan = 20 },
new JoinMetadata
{
Description = "Source Keys",
@@ -422,8 +459,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("SourceTypeJoinStart")] public JoinDataComplete SourceTypeJoinStart =
- new JoinDataComplete(new JoinData {JoinNumber = 661, JoinSpan = 20},
+ [JoinName("SourceTypeJoinStart")]
+ public JoinDataComplete SourceTypeJoinStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 661, JoinSpan = 20 },
new JoinMetadata
{
Description = "Source Types",
@@ -431,8 +469,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CameraNearNameStart")] public JoinDataComplete CameraNearNameStart =
- new JoinDataComplete(new JoinData {JoinNumber = 761, JoinSpan = 10},
+ [JoinName("CameraNearNameStart")]
+ public JoinDataComplete CameraNearNameStart =
+ new JoinDataComplete(new JoinData { JoinNumber = 761, JoinSpan = 10 },
new JoinMetadata
{
Description = "Near End Camera Names",
@@ -440,8 +479,9 @@ public class MobileControlSIMPLRoomJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CameraFarName")] public JoinDataComplete CameraFarName =
- new JoinDataComplete(new JoinData {JoinNumber = 771, JoinSpan = 1},
+ [JoinName("CameraFarName")]
+ public JoinDataComplete CameraFarName =
+ new JoinDataComplete(new JoinData { JoinNumber = 771, JoinSpan = 1 },
new JoinMetadata
{
Description = "Far End Camera Name",
diff --git a/3-series/SIMPLJoinMaps/MobileControlSIMPLRunDirectRouteActionJoinMap.cs b/3-series/SIMPLJoinMaps/MobileControlSIMPLRunDirectRouteActionJoinMap.cs
index ef906ee..10c516e 100644
--- a/3-series/SIMPLJoinMaps/MobileControlSIMPLRunDirectRouteActionJoinMap.cs
+++ b/3-series/SIMPLJoinMaps/MobileControlSIMPLRunDirectRouteActionJoinMap.cs
@@ -1,9 +1,8 @@
-using System;
-using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer
{
- public class MobileControlSIMPLRunDirectRouteActionJoinMap:JoinMapBaseAdvanced
+ public class MobileControlSIMPLRunDirectRouteActionJoinMap : JoinMapBaseAdvanced
{
[JoinName("AdvancedSharingModeFb")]
public JoinDataComplete AdvancedSharingModeFb =
@@ -57,7 +56,7 @@ public class MobileControlSIMPLRunDirectRouteActionJoinMap:JoinMapBaseAdvanced
[JoinName("SourceForDestinationAudio")]
public JoinDataComplete SourceForDestinationAudio =
- new JoinDataComplete(new JoinData {JoinNumber = 61, JoinSpan = 1},
+ new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1 },
new JoinMetadata
{
Description = "Source to Route to Destination & FB",
diff --git a/3-series/SIMPLJoinMaps/SIMPLAtcJoinMap.cs b/3-series/SIMPLJoinMaps/SIMPLAtcJoinMap.cs
index 56bc1c2..0ec4de5 100644
--- a/3-series/SIMPLJoinMaps/SIMPLAtcJoinMap.cs
+++ b/3-series/SIMPLJoinMaps/SIMPLAtcJoinMap.cs
@@ -5,8 +5,9 @@ namespace PepperDash.Essentials.AppServer
{
public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
{
- [JoinName("EndCall")] public JoinDataComplete EndCall =
- new JoinDataComplete(new JoinData() {JoinNumber = 21, JoinSpan = 1},
+ [JoinName("EndCall")]
+ public JoinDataComplete EndCall =
+ new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Hang Up",
@@ -14,8 +15,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("IncomingAnswer")] public JoinDataComplete IncomingAnswer =
- new JoinDataComplete(new JoinData() {JoinNumber = 51, JoinSpan = 1},
+ [JoinName("IncomingAnswer")]
+ public JoinDataComplete IncomingAnswer =
+ new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Answer Incoming Call",
@@ -23,8 +25,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("IncomingReject")] public JoinDataComplete IncomingReject =
- new JoinDataComplete(new JoinData() {JoinNumber = 52, JoinSpan = 1},
+ [JoinName("IncomingReject")]
+ public JoinDataComplete IncomingReject =
+ new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Reject Incoming Call",
@@ -32,8 +35,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("SpeedDialStart")] public JoinDataComplete SpeedDialStart =
- new JoinDataComplete(new JoinData() {JoinNumber = 41, JoinSpan = 4},
+ [JoinName("SpeedDialStart")]
+ public JoinDataComplete SpeedDialStart =
+ new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 },
new JoinMetadata()
{
Description = "Speed Dial",
@@ -41,8 +45,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CurrentDialString")] public JoinDataComplete CurrentDialString =
- new JoinDataComplete(new JoinData() {JoinNumber = 1, JoinSpan = 1},
+ [JoinName("CurrentDialString")]
+ public JoinDataComplete CurrentDialString =
+ new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Dial String",
@@ -50,8 +55,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CurrentCallNumber")] public JoinDataComplete CurrentCallNumber =
- new JoinDataComplete(new JoinData() {JoinNumber = 11, JoinSpan = 1},
+ [JoinName("CurrentCallNumber")]
+ public JoinDataComplete CurrentCallNumber =
+ new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Call Number",
@@ -59,8 +65,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CurrentCallName")] public JoinDataComplete CurrentCallName =
- new JoinDataComplete(new JoinData() {JoinNumber = 12, JoinSpan = 1},
+ [JoinName("CurrentCallName")]
+ public JoinDataComplete CurrentCallName =
+ new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Call Name",
@@ -68,8 +75,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("HookState")] public JoinDataComplete HookState =
- new JoinDataComplete(new JoinData() {JoinNumber = 21, JoinSpan = 1},
+ [JoinName("HookState")]
+ public JoinDataComplete HookState =
+ new JoinDataComplete(new JoinData() { JoinNumber = 21, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Hook State",
@@ -77,8 +85,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CallDirection")] public JoinDataComplete CallDirection =
- new JoinDataComplete(new JoinData() {JoinNumber = 22, JoinSpan = 1},
+ [JoinName("CallDirection")]
+ public JoinDataComplete CallDirection =
+ new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Call Direction",
@@ -86,8 +95,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("IncomingCallName")] public JoinDataComplete IncomingCallName =
- new JoinDataComplete(new JoinData() {JoinNumber = 51, JoinSpan = 1},
+ [JoinName("IncomingCallName")]
+ public JoinDataComplete IncomingCallName =
+ new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Incoming Call Name",
@@ -95,8 +105,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("IncomingCallNumber")] public JoinDataComplete IncomingCallNumber =
- new JoinDataComplete(new JoinData() {JoinNumber = 52, JoinSpan = 1},
+ [JoinName("IncomingCallNumber")]
+ public JoinDataComplete IncomingCallNumber =
+ new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Incoming Call Number",
@@ -104,8 +115,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("0")] public JoinDataComplete Dtmf0 =
- new JoinDataComplete(new JoinData() {JoinNumber = 10, JoinSpan = 1},
+ [JoinName("0")]
+ public JoinDataComplete Dtmf0 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 0",
@@ -113,8 +125,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("1")] public JoinDataComplete Dtmf1 =
- new JoinDataComplete(new JoinData() {JoinNumber = 1, JoinSpan = 1},
+ [JoinName("1")]
+ public JoinDataComplete Dtmf1 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 1",
@@ -122,8 +135,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("2")] public JoinDataComplete Dtmf2 =
- new JoinDataComplete(new JoinData() {JoinNumber = 2, JoinSpan = 1},
+ [JoinName("2")]
+ public JoinDataComplete Dtmf2 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 2",
@@ -131,8 +145,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("3")] public JoinDataComplete Dtmf3 =
- new JoinDataComplete(new JoinData() {JoinNumber = 3, JoinSpan = 1},
+ [JoinName("3")]
+ public JoinDataComplete Dtmf3 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 3",
@@ -140,8 +155,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("4")] public JoinDataComplete Dtmf4 =
- new JoinDataComplete(new JoinData() {JoinNumber = 4, JoinSpan = 1},
+ [JoinName("4")]
+ public JoinDataComplete Dtmf4 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 4",
@@ -149,8 +165,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("5")] public JoinDataComplete Dtmf5 =
- new JoinDataComplete(new JoinData() {JoinNumber = 5, JoinSpan = 1},
+ [JoinName("5")]
+ public JoinDataComplete Dtmf5 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 5",
@@ -158,8 +175,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("6")] public JoinDataComplete Dtmf6 =
- new JoinDataComplete(new JoinData() {JoinNumber = 6, JoinSpan = 1},
+ [JoinName("6")]
+ public JoinDataComplete Dtmf6 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 6",
@@ -167,8 +185,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("7")] public JoinDataComplete Dtmf7 =
- new JoinDataComplete(new JoinData() {JoinNumber = 7, JoinSpan = 1},
+ [JoinName("7")]
+ public JoinDataComplete Dtmf7 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 7",
@@ -176,8 +195,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("8")] public JoinDataComplete Dtmf8 =
- new JoinDataComplete(new JoinData() {JoinNumber = 8, JoinSpan = 1},
+ [JoinName("8")]
+ public JoinDataComplete Dtmf8 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 8",
@@ -185,8 +205,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("9")] public JoinDataComplete Dtmf9 =
- new JoinDataComplete(new JoinData() {JoinNumber = 9, JoinSpan = 1},
+ [JoinName("9")]
+ public JoinDataComplete Dtmf9 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 9",
@@ -194,8 +215,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("*")] public JoinDataComplete DtmfStar =
- new JoinDataComplete(new JoinData() {JoinNumber = 11, JoinSpan = 1},
+ [JoinName("*")]
+ public JoinDataComplete DtmfStar =
+ new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF *",
@@ -203,8 +225,9 @@ public class SIMPLAtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("#")] public JoinDataComplete DtmfPound =
- new JoinDataComplete(new JoinData() {JoinNumber = 12, JoinSpan = 1},
+ [JoinName("#")]
+ public JoinDataComplete DtmfPound =
+ new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF #",
diff --git a/3-series/SIMPLJoinMaps/SIMPLVtcJoinMap.cs b/3-series/SIMPLJoinMaps/SIMPLVtcJoinMap.cs
index ad89fd8..69b3249 100644
--- a/3-series/SIMPLJoinMaps/SIMPLVtcJoinMap.cs
+++ b/3-series/SIMPLJoinMaps/SIMPLVtcJoinMap.cs
@@ -5,8 +5,9 @@ namespace PepperDash.Essentials.AppServer
{
public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
{
- [JoinName("EndCall")] public JoinDataComplete EndCall =
- new JoinDataComplete(new JoinData() {JoinNumber = 24, JoinSpan = 1},
+ [JoinName("EndCall")]
+ public JoinDataComplete EndCall =
+ new JoinDataComplete(new JoinData() { JoinNumber = 24, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Hang Up",
@@ -14,8 +15,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("IncomingCall")] public JoinDataComplete IncomingCall =
- new JoinDataComplete(new JoinData() {JoinNumber = 50, JoinSpan = 1},
+ [JoinName("IncomingCall")]
+ public JoinDataComplete IncomingCall =
+ new JoinDataComplete(new JoinData() { JoinNumber = 50, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Incoming Call",
@@ -23,8 +25,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("IncomingAnswer")] public JoinDataComplete IncomingAnswer =
- new JoinDataComplete(new JoinData() {JoinNumber = 51, JoinSpan = 1},
+ [JoinName("IncomingAnswer")]
+ public JoinDataComplete IncomingAnswer =
+ new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Answer Incoming Call",
@@ -32,8 +35,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("IncomingReject")] public JoinDataComplete IncomingReject =
- new JoinDataComplete(new JoinData() {JoinNumber = 52, JoinSpan = 1},
+ [JoinName("IncomingReject")]
+ public JoinDataComplete IncomingReject =
+ new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Reject Incoming Call",
@@ -41,8 +45,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("SpeedDialStart")] public JoinDataComplete SpeedDialStart =
- new JoinDataComplete(new JoinData() {JoinNumber = 41, JoinSpan = 4},
+ [JoinName("SpeedDialStart")]
+ public JoinDataComplete SpeedDialStart =
+ new JoinDataComplete(new JoinData() { JoinNumber = 41, JoinSpan = 4 },
new JoinMetadata()
{
Description = "Speed Dial",
@@ -50,8 +55,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectorySearchBusy")] public JoinDataComplete DirectorySearchBusy =
- new JoinDataComplete(new JoinData() {JoinNumber = 100, JoinSpan = 1},
+ [JoinName("DirectorySearchBusy")]
+ public JoinDataComplete DirectorySearchBusy =
+ new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory Search Busy FB",
@@ -59,8 +65,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectoryLineSelected")] public JoinDataComplete DirectoryLineSelected =
- new JoinDataComplete(new JoinData() {JoinNumber = 101, JoinSpan = 1},
+ [JoinName("DirectoryLineSelected")]
+ public JoinDataComplete DirectoryLineSelected =
+ new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory Line Selected FB",
@@ -68,8 +75,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectoryEntryIsContact")] public JoinDataComplete DirectoryEntryIsContact =
- new JoinDataComplete(new JoinData() {JoinNumber = 101, JoinSpan = 1},
+ [JoinName("DirectoryEntryIsContact")]
+ public JoinDataComplete DirectoryEntryIsContact =
+ new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory Selected Entry Is Contact FB",
@@ -77,8 +85,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectoryIsRoot")] public JoinDataComplete DirectoryIsRoot =
- new JoinDataComplete(new JoinData() {JoinNumber = 102, JoinSpan = 1},
+ [JoinName("DirectoryIsRoot")]
+ public JoinDataComplete DirectoryIsRoot =
+ new JoinDataComplete(new JoinData() { JoinNumber = 102, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory is on Root FB",
@@ -86,8 +95,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DDirectoryHasChanged")] public JoinDataComplete DDirectoryHasChanged =
- new JoinDataComplete(new JoinData() {JoinNumber = 103, JoinSpan = 1},
+ [JoinName("DDirectoryHasChanged")]
+ public JoinDataComplete DDirectoryHasChanged =
+ new JoinDataComplete(new JoinData() { JoinNumber = 103, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory has changed FB",
@@ -95,8 +105,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectoryRoot")] public JoinDataComplete DirectoryRoot =
- new JoinDataComplete(new JoinData() {JoinNumber = 104, JoinSpan = 1},
+ [JoinName("DirectoryRoot")]
+ public JoinDataComplete DirectoryRoot =
+ new JoinDataComplete(new JoinData() { JoinNumber = 104, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Go to Directory Root",
@@ -104,8 +115,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectoryFolderBack")] public JoinDataComplete DirectoryFolderBack =
- new JoinDataComplete(new JoinData() {JoinNumber = 105, JoinSpan = 1},
+ [JoinName("DirectoryFolderBack")]
+ public JoinDataComplete DirectoryFolderBack =
+ new JoinDataComplete(new JoinData() { JoinNumber = 105, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Go back one directory level",
@@ -113,8 +125,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectoryDialSelectedLine")] public JoinDataComplete DirectoryDialSelectedLine =
- new JoinDataComplete(new JoinData() {JoinNumber = 106, JoinSpan = 1},
+ [JoinName("DirectoryDialSelectedLine")]
+ public JoinDataComplete DirectoryDialSelectedLine =
+ new JoinDataComplete(new JoinData() { JoinNumber = 106, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Dial selected directory line",
@@ -122,8 +135,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraTiltUp")] public JoinDataComplete CameraTiltUp =
- new JoinDataComplete(new JoinData() {JoinNumber = 111, JoinSpan = 1},
+ [JoinName("CameraTiltUp")]
+ public JoinDataComplete CameraTiltUp =
+ new JoinDataComplete(new JoinData() { JoinNumber = 111, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Tilt Up",
@@ -131,8 +145,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraTiltDown")] public JoinDataComplete CameraTiltDown =
- new JoinDataComplete(new JoinData() {JoinNumber = 112, JoinSpan = 1},
+ [JoinName("CameraTiltDown")]
+ public JoinDataComplete CameraTiltDown =
+ new JoinDataComplete(new JoinData() { JoinNumber = 112, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Tilt Down",
@@ -140,8 +155,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraPanLeft")] public JoinDataComplete CameraPanLeft =
- new JoinDataComplete(new JoinData() {JoinNumber = 113, JoinSpan = 1},
+ [JoinName("CameraPanLeft")]
+ public JoinDataComplete CameraPanLeft =
+ new JoinDataComplete(new JoinData() { JoinNumber = 113, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Pan Left",
@@ -149,8 +165,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraPanRight")] public JoinDataComplete CameraPanRight =
- new JoinDataComplete(new JoinData() {JoinNumber = 114, JoinSpan = 1},
+ [JoinName("CameraPanRight")]
+ public JoinDataComplete CameraPanRight =
+ new JoinDataComplete(new JoinData() { JoinNumber = 114, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Pan Right",
@@ -158,8 +175,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraZoomIn")] public JoinDataComplete CameraZoomIn =
- new JoinDataComplete(new JoinData() {JoinNumber = 115, JoinSpan = 1},
+ [JoinName("CameraZoomIn")]
+ public JoinDataComplete CameraZoomIn =
+ new JoinDataComplete(new JoinData() { JoinNumber = 115, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Zoom In",
@@ -167,8 +185,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraZoomOut")] public JoinDataComplete CameraZoomOut =
- new JoinDataComplete(new JoinData() {JoinNumber = 116, JoinSpan = 1},
+ [JoinName("CameraZoomOut")]
+ public JoinDataComplete CameraZoomOut =
+ new JoinDataComplete(new JoinData() { JoinNumber = 116, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Zoom Out",
@@ -176,8 +195,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraPresetStart")] public JoinDataComplete CameraPresetStart =
- new JoinDataComplete(new JoinData() {JoinNumber = 121, JoinSpan = 5},
+ [JoinName("CameraPresetStart")]
+ public JoinDataComplete CameraPresetStart =
+ new JoinDataComplete(new JoinData() { JoinNumber = 121, JoinSpan = 5 },
new JoinMetadata()
{
Description = "Camera Presets",
@@ -185,8 +205,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraModeAuto")] public JoinDataComplete CameraModeAuto =
- new JoinDataComplete(new JoinData() {JoinNumber = 131, JoinSpan = 1},
+ [JoinName("CameraModeAuto")]
+ public JoinDataComplete CameraModeAuto =
+ new JoinDataComplete(new JoinData() { JoinNumber = 131, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Mode Auto",
@@ -194,8 +215,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraModeManual")] public JoinDataComplete CameraModeManual =
- new JoinDataComplete(new JoinData() {JoinNumber = 132, JoinSpan = 1},
+ [JoinName("CameraModeManual")]
+ public JoinDataComplete CameraModeManual =
+ new JoinDataComplete(new JoinData() { JoinNumber = 132, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Mode Manual",
@@ -203,8 +225,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraModeOff")] public JoinDataComplete CameraModeOff =
- new JoinDataComplete(new JoinData() {JoinNumber = 133, JoinSpan = 1},
+ [JoinName("CameraModeOff")]
+ public JoinDataComplete CameraModeOff =
+ new JoinDataComplete(new JoinData() { JoinNumber = 133, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Mode Off",
@@ -212,8 +235,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraSelfView")] public JoinDataComplete CameraSelfView =
- new JoinDataComplete(new JoinData() {JoinNumber = 141, JoinSpan = 1},
+ [JoinName("CameraSelfView")]
+ public JoinDataComplete CameraSelfView =
+ new JoinDataComplete(new JoinData() { JoinNumber = 141, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Self View Toggle/FB",
@@ -221,8 +245,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraLayout")] public JoinDataComplete CameraLayout =
- new JoinDataComplete(new JoinData() {JoinNumber = 142, JoinSpan = 1},
+ [JoinName("CameraLayout")]
+ public JoinDataComplete CameraLayout =
+ new JoinDataComplete(new JoinData() { JoinNumber = 142, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Layout Toggle",
@@ -230,8 +255,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraSupportsAutoMode")] public JoinDataComplete CameraSupportsAutoMode =
- new JoinDataComplete(new JoinData() {JoinNumber = 143, JoinSpan = 1},
+ [JoinName("CameraSupportsAutoMode")]
+ public JoinDataComplete CameraSupportsAutoMode =
+ new JoinDataComplete(new JoinData() { JoinNumber = 143, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Supports Auto Mode FB",
@@ -239,8 +265,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraSupportsOffMode")] public JoinDataComplete CameraSupportsOffMode =
- new JoinDataComplete(new JoinData() {JoinNumber = 144, JoinSpan = 1},
+ [JoinName("CameraSupportsOffMode")]
+ public JoinDataComplete CameraSupportsOffMode =
+ new JoinDataComplete(new JoinData() { JoinNumber = 144, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Supports Off Mode FB",
@@ -248,8 +275,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("CameraNumberSelect")] public JoinDataComplete CameraNumberSelect =
- new JoinDataComplete(new JoinData() {JoinNumber = 60, JoinSpan = 1},
+ [JoinName("CameraNumberSelect")]
+ public JoinDataComplete CameraNumberSelect =
+ new JoinDataComplete(new JoinData() { JoinNumber = 60, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Camera Number Select/FB",
@@ -257,8 +285,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("DirectorySelectRow")] public JoinDataComplete DirectorySelectRow =
- new JoinDataComplete(new JoinData() {JoinNumber = 101, JoinSpan = 1},
+ [JoinName("DirectorySelectRow")]
+ public JoinDataComplete DirectorySelectRow =
+ new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory Select Row",
@@ -266,8 +295,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Analog
});
- [JoinName("DirectoryRowCount")] public JoinDataComplete DirectoryRowCount =
- new JoinDataComplete(new JoinData() {JoinNumber = 101, JoinSpan = 1},
+ [JoinName("DirectoryRowCount")]
+ public JoinDataComplete DirectoryRowCount =
+ new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory Row Count FB",
@@ -275,8 +305,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Analog
});
- [JoinName("CurrentDialString")] public JoinDataComplete CurrentDialString =
- new JoinDataComplete(new JoinData() {JoinNumber = 1, JoinSpan = 1},
+ [JoinName("CurrentDialString")]
+ public JoinDataComplete CurrentDialString =
+ new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Dial String",
@@ -284,8 +315,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CurrentCallName")] public JoinDataComplete CurrentCallName =
- new JoinDataComplete(new JoinData() {JoinNumber = 2, JoinSpan = 1},
+ [JoinName("CurrentCallName")]
+ public JoinDataComplete CurrentCallName =
+ new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Call Name",
@@ -293,8 +325,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CurrentCallNumber")] public JoinDataComplete CurrentCallNumber =
- new JoinDataComplete(new JoinData() {JoinNumber = 3, JoinSpan = 1},
+ [JoinName("CurrentCallNumber")]
+ public JoinDataComplete CurrentCallNumber =
+ new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Call Number",
@@ -302,8 +335,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("HookState")] public JoinDataComplete HookState =
- new JoinDataComplete(new JoinData() {JoinNumber = 31, JoinSpan = 1},
+ [JoinName("HookState")]
+ public JoinDataComplete HookState =
+ new JoinDataComplete(new JoinData() { JoinNumber = 31, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Hook State",
@@ -311,8 +345,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("CallDirection")] public JoinDataComplete CallDirection =
- new JoinDataComplete(new JoinData() {JoinNumber = 22, JoinSpan = 1},
+ [JoinName("CallDirection")]
+ public JoinDataComplete CallDirection =
+ new JoinDataComplete(new JoinData() { JoinNumber = 22, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Current Call Direction",
@@ -320,8 +355,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("IncomingCallName")] public JoinDataComplete IncomingCallName =
- new JoinDataComplete(new JoinData() {JoinNumber = 51, JoinSpan = 1},
+ [JoinName("IncomingCallName")]
+ public JoinDataComplete IncomingCallName =
+ new JoinDataComplete(new JoinData() { JoinNumber = 51, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Incoming Call Name",
@@ -329,8 +365,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("IncomingCallNumber")] public JoinDataComplete IncomingCallNumber =
- new JoinDataComplete(new JoinData() {JoinNumber = 52, JoinSpan = 1},
+ [JoinName("IncomingCallNumber")]
+ public JoinDataComplete IncomingCallNumber =
+ new JoinDataComplete(new JoinData() { JoinNumber = 52, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Incoming Call Number",
@@ -338,8 +375,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("DirectorySearchString")] public JoinDataComplete DirectorySearchString =
- new JoinDataComplete(new JoinData() {JoinNumber = 100, JoinSpan = 1},
+ [JoinName("DirectorySearchString")]
+ public JoinDataComplete DirectorySearchString =
+ new JoinDataComplete(new JoinData() { JoinNumber = 100, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Directory Search String",
@@ -347,8 +385,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("DirectoryEntriesStart")] public JoinDataComplete DirectoryEntriesStart =
- new JoinDataComplete(new JoinData() {JoinNumber = 101, JoinSpan = 255},
+ [JoinName("DirectoryEntriesStart")]
+ public JoinDataComplete DirectoryEntriesStart =
+ new JoinDataComplete(new JoinData() { JoinNumber = 101, JoinSpan = 255 },
new JoinMetadata()
{
Description = "Directory Entries",
@@ -356,8 +395,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("DirectoryEntrySelectedName")] public JoinDataComplete DirectoryEntrySelectedName =
- new JoinDataComplete(new JoinData() {JoinNumber = 356, JoinSpan = 1},
+ [JoinName("DirectoryEntrySelectedName")]
+ public JoinDataComplete DirectoryEntrySelectedName =
+ new JoinDataComplete(new JoinData() { JoinNumber = 356, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Selected Directory Entry Name",
@@ -365,8 +405,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("DirectoryEntrySelectedNumber")] public JoinDataComplete DirectoryEntrySelectedNumber =
- new JoinDataComplete(new JoinData() {JoinNumber = 357, JoinSpan = 1},
+ [JoinName("DirectoryEntrySelectedNumber")]
+ public JoinDataComplete DirectoryEntrySelectedNumber =
+ new JoinDataComplete(new JoinData() { JoinNumber = 357, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Selected Directory Entry Number",
@@ -374,8 +415,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("DirectorySelectedFolderName")] public JoinDataComplete DirectorySelectedFolderName =
- new JoinDataComplete(new JoinData() {JoinNumber = 358, JoinSpan = 1},
+ [JoinName("DirectorySelectedFolderName")]
+ public JoinDataComplete DirectorySelectedFolderName =
+ new JoinDataComplete(new JoinData() { JoinNumber = 358, JoinSpan = 1 },
new JoinMetadata()
{
Description = "Selected Directory Folder Name",
@@ -383,8 +425,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Serial
});
- [JoinName("1")] public JoinDataComplete Dtmf1 =
- new JoinDataComplete(new JoinData() {JoinNumber = 1, JoinSpan = 1},
+ [JoinName("1")]
+ public JoinDataComplete Dtmf1 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 1",
@@ -392,8 +435,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("2")] public JoinDataComplete Dtmf2 =
- new JoinDataComplete(new JoinData() {JoinNumber = 2, JoinSpan = 1},
+ [JoinName("2")]
+ public JoinDataComplete Dtmf2 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 2",
@@ -401,8 +445,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("3")] public JoinDataComplete Dtmf3 =
- new JoinDataComplete(new JoinData() {JoinNumber = 3, JoinSpan = 1},
+ [JoinName("3")]
+ public JoinDataComplete Dtmf3 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 3",
@@ -410,8 +455,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("4")] public JoinDataComplete Dtmf4 =
- new JoinDataComplete(new JoinData() {JoinNumber = 4, JoinSpan = 1},
+ [JoinName("4")]
+ public JoinDataComplete Dtmf4 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 4",
@@ -419,8 +465,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("5")] public JoinDataComplete Dtmf5 =
- new JoinDataComplete(new JoinData() {JoinNumber = 5, JoinSpan = 1},
+ [JoinName("5")]
+ public JoinDataComplete Dtmf5 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 5, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 5",
@@ -428,8 +475,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("6")] public JoinDataComplete Dtmf6 =
- new JoinDataComplete(new JoinData() {JoinNumber = 6, JoinSpan = 1},
+ [JoinName("6")]
+ public JoinDataComplete Dtmf6 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 6, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 6",
@@ -437,8 +485,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("7")] public JoinDataComplete Dtmf7 =
- new JoinDataComplete(new JoinData() {JoinNumber = 7, JoinSpan = 1},
+ [JoinName("7")]
+ public JoinDataComplete Dtmf7 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 7, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 7",
@@ -446,8 +495,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("8")] public JoinDataComplete Dtmf8 =
- new JoinDataComplete(new JoinData() {JoinNumber = 8, JoinSpan = 1},
+ [JoinName("8")]
+ public JoinDataComplete Dtmf8 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 8, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 8",
@@ -455,8 +505,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("9")] public JoinDataComplete Dtmf9 =
- new JoinDataComplete(new JoinData() {JoinNumber = 9, JoinSpan = 1},
+ [JoinName("9")]
+ public JoinDataComplete Dtmf9 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 9, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 9",
@@ -464,8 +515,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("0")] public JoinDataComplete Dtmf0 =
- new JoinDataComplete(new JoinData() {JoinNumber = 10, JoinSpan = 1},
+ [JoinName("0")]
+ public JoinDataComplete Dtmf0 =
+ new JoinDataComplete(new JoinData() { JoinNumber = 10, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF 0",
@@ -473,8 +525,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("*")] public JoinDataComplete DtmfStar =
- new JoinDataComplete(new JoinData() {JoinNumber = 11, JoinSpan = 1},
+ [JoinName("*")]
+ public JoinDataComplete DtmfStar =
+ new JoinDataComplete(new JoinData() { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF *",
@@ -482,8 +535,9 @@ public class SIMPLVtcJoinMap : JoinMapBaseAdvanced
JoinType = eJoinType.Digital
});
- [JoinName("#")] public JoinDataComplete DtmfPound =
- new JoinDataComplete(new JoinData() {JoinNumber = 12, JoinSpan = 1},
+ [JoinName("#")]
+ public JoinDataComplete DtmfPound =
+ new JoinDataComplete(new JoinData() { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata()
{
Description = "DTMF #",
diff --git a/3-series/TransmitMessage.cs b/3-series/TransmitMessage.cs
index 923cf3b..912d6af 100644
--- a/3-series/TransmitMessage.cs
+++ b/3-series/TransmitMessage.cs
@@ -42,7 +42,7 @@ public void Dispatch()
if (_ws != null && _ws.IsAlive)
{
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
- new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = {new IsoDateTimeConverter()} });
+ new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
Debug.Console(2, "Message TX: {0}", message);
@@ -94,26 +94,26 @@ public MessageToClients(DeviceStateMessageBase msg, MobileControlWebsocketServer
public void Dispatch()
{
try
- {
+ {
//Debug.Console(2, "Message: {0}", msgToSend.ToString());
if (_server != null)
{
Debug.Console(2, _server, Debug.ErrorLogLevel.Notice, "Dispatching message type: {0}", msgToSend.GetType());
-
+
var message = JsonConvert.SerializeObject(msgToSend, Formatting.None,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = { new IsoDateTimeConverter() } });
- var clientSpecificMessage = msgToSend as MobileControlResponseMessage;
- if (clientSpecificMessage != null)
+ var clientSpecificMessage = msgToSend as MobileControlMessage;
+ if (clientSpecificMessage.ClientId != null)
{
var clientId = clientSpecificMessage.ClientId;
- Debug.Console(2, _server, "Message TX To Client ID: {0} Message: {1}", clientId, message);
+ Debug.Console(2, _server, "Message TX To Client ID: {0} Message: {1}", clientId, message);
_server.SendMessageToClient(clientId, message);
}
- else
+ else
{
_server.SendMessageToAllClients(message);
@@ -125,7 +125,7 @@ public void Dispatch()
Debug.Console(1, "Cannot send. No server.");
}
}
- catch(ThreadAbortException)
+ catch (ThreadAbortException)
{
//Swallowing this exception, as it occurs on shutdown and there's no need to print out a scary stack trace
}
@@ -134,7 +134,7 @@ public void Dispatch()
Debug.Console(0, Debug.ErrorLogLevel.Error, "Caught an exception in the Transmit Processor {0}", ex.Message);
Debug.Console(2, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
- if(ex.InnerException != null)
+ if (ex.InnerException != null)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "----\r\n{0}", ex.InnerException.Message);
Debug.Console(2, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.InnerException.StackTrace);
diff --git a/3-series/Volumes.cs b/3-series/Volumes.cs
index d206906..8855667 100644
--- a/3-series/Volumes.cs
+++ b/3-series/Volumes.cs
@@ -1,5 +1,5 @@
-using System.Collections.Generic;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
+using System.Collections.Generic;
namespace PepperDash.Essentials.Room.MobileControl
{
@@ -63,7 +63,7 @@ public Volume(string key, int level)
}
public Volume(string key, bool muted)
- :this(key)
+ : this(key)
{
Muted = muted;
}
diff --git a/4-series/Directory.Build.targets b/4-series/Directory.Build.targets
index 1b1c73d..807679e 100644
--- a/4-series/Directory.Build.targets
+++ b/4-series/Directory.Build.targets
@@ -25,14 +25,4 @@
-
-
-
- doNotUse
-
-
- doNotUse2
-
-
-
diff --git a/4-series/epi-essentials-mobile-control/AuthorizationResponse.cs b/4-series/epi-essentials-mobile-control/AuthorizationResponse.cs
new file mode 100644
index 0000000..4e4a443
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/AuthorizationResponse.cs
@@ -0,0 +1,19 @@
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials
+{
+ public class AuthorizationResponse
+ {
+ [JsonProperty("authorized")]
+ public bool Authorized { get; set; }
+
+ [JsonProperty("reason", NullValueHandling = NullValueHandling.Ignore)]
+ public string Reason { get; set; } = null;
+ }
+
+ public class AuthorizationRequest
+ {
+ [JsonProperty("grantCode")]
+ public string GrantCode { get; set; }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/MobileControlAction.cs b/4-series/epi-essentials-mobile-control/MobileControlAction.cs
new file mode 100644
index 0000000..ac09fbc
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/MobileControlAction.cs
@@ -0,0 +1,23 @@
+using Newtonsoft.Json.Linq;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Web.RequestHandlers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials
+{
+ public class MobileControlAction : IMobileControlAction
+ {
+ public IMobileControlMessenger Messenger { get; private set; }
+
+ public Action Action {get; private set; }
+
+ public MobileControlAction(IMobileControlMessenger messenger, Action handler) {
+ Messenger = messenger;
+ Action = handler;
+ }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/Services/MobileControlApiService.cs b/4-series/epi-essentials-mobile-control/Services/MobileControlApiService.cs
new file mode 100644
index 0000000..eeafcec
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/Services/MobileControlApiService.cs
@@ -0,0 +1,67 @@
+using PepperDash.Core;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.Services
+{
+
+ public class MobileControlApiService
+ {
+ private readonly HttpClient _client;
+
+ public MobileControlApiService(string apiUrl)
+ {
+ var handler = new HttpClientHandler
+ {
+ AllowAutoRedirect = false,
+ };
+
+ _client = new HttpClient(handler);
+ }
+
+ public async Task SendAuthorizationRequest(string apiUrl, string grantCode, string systemUuid)
+ {
+ var request = new HttpRequestMessage(HttpMethod.Get, $"{apiUrl}/system/{systemUuid}/authorize?grantCode={grantCode}");
+
+ Debug.Console(1, $"Sending authorization request to {request.RequestUri}");
+
+ var response = await _client.SendAsync(request);
+
+ var authResponse = new AuthorizationResponse
+ {
+ Authorized = response.StatusCode == System.Net.HttpStatusCode.OK
+ };
+
+ if (authResponse.Authorized)
+ {
+ return authResponse;
+ }
+
+ if (response.StatusCode == System.Net.HttpStatusCode.Moved)
+ {
+ var location = response.Headers.Location;
+
+ authResponse.Reason = $"ERROR: Mobile Control API has moved. Please adjust configuration to \"{location}\"";
+
+ return authResponse;
+ }
+
+ var responseString = await response.Content.ReadAsStringAsync();
+
+ switch (responseString)
+ {
+ case "codeNotFound":
+ authResponse.Reason = $"Authorization failed. Code not found for system UUID {systemUuid}";
+ break;
+ case "uuidNotFound":
+ authResponse.Reason = $"Authorization failed. System UUID {systemUuid} not found. Check Essentials configuration.";
+ break;
+ default:
+ authResponse.Reason = $"Authorization failed. Response {response.StatusCode}: {responseString}";
+ break;
+ }
+
+ return authResponse;
+ }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/Touchpanel/ITswAppControl.cs b/4-series/epi-essentials-mobile-control/Touchpanel/ITswAppControl.cs
new file mode 100644
index 0000000..814b51c
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/Touchpanel/ITswAppControl.cs
@@ -0,0 +1,25 @@
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.Touchpanel
+{
+ public interface ITswAppControl : IKeyed
+ {
+ BoolFeedback AppOpenFeedback { get; }
+
+ void HideOpenApp();
+
+ void CloseOpenApp();
+
+ void OpenApp();
+ }
+
+ public interface ITswZoomControl : IKeyed
+ {
+ BoolFeedback ZoomIncomingCallFeedback { get; }
+
+ BoolFeedback ZoomInCallFeedback { get; }
+
+ void EndZoomCall();
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/Touchpanel/ITswAppControlMessenger.cs b/4-series/epi-essentials-mobile-control/Touchpanel/ITswAppControlMessenger.cs
new file mode 100644
index 0000000..52fa693
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/Touchpanel/ITswAppControlMessenger.cs
@@ -0,0 +1,59 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+
+namespace PepperDash.Essentials.Touchpanel
+{
+ public class ITswAppControlMessenger : MessengerBase
+ {
+ private readonly ITswAppControl _appControl;
+
+ public ITswAppControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ _appControl = device as ITswAppControl;
+ }
+
+ protected override void RegisterActions()
+ {
+ if (_appControl == null)
+ {
+ Debug.Console(0, this, $"{_device.Key} does not implement ITswAppControl");
+ return;
+ }
+
+ AddAction($"/fullStatus", (id, context) => SendFullStatus());
+
+ AddAction($"/openApp", (id, context) => _appControl.OpenApp());
+
+ AddAction($"/closeApp", (id, context) => _appControl.CloseOpenApp());
+
+ AddAction($"/hideApp", (id, context) => _appControl.HideOpenApp());
+
+ _appControl.AppOpenFeedback.OutputChange += (s, a) =>
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ appOpen = a.BoolValue
+ }));
+ };
+ }
+
+ private void SendFullStatus()
+ {
+ var message = new TswAppStateMessage
+ {
+ AppOpen = _appControl.AppOpenFeedback.BoolValue,
+ };
+
+ PostStatusMessage(message);
+ }
+ }
+
+ public class TswAppStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("appOpen", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? AppOpen { get; set; }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/Touchpanel/ITswZoomControlMessenger.cs b/4-series/epi-essentials-mobile-control/Touchpanel/ITswZoomControlMessenger.cs
new file mode 100644
index 0000000..51ff355
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/Touchpanel/ITswZoomControlMessenger.cs
@@ -0,0 +1,71 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+
+
+namespace PepperDash.Essentials.Touchpanel
+{
+ public class ITswZoomControlMessenger : MessengerBase
+ {
+ private readonly ITswZoomControl _zoomControl;
+
+ public ITswZoomControlMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ _zoomControl = device as ITswZoomControl;
+ }
+
+ protected override void RegisterActions()
+ {
+ if (_zoomControl == null)
+ {
+ Debug.Console(0, this, $"{_device.Key} does not implement ITswZoomControl");
+ return;
+ }
+
+ AddAction($"/fullStatus", (id, context) => SendFullStatus());
+
+
+ AddAction($"/endCall", (id, context) => _zoomControl.EndZoomCall());
+
+ _zoomControl.ZoomIncomingCallFeedback.OutputChange += (s, a) =>
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ incomingCall = a.BoolValue,
+ }));
+ };
+
+
+ _zoomControl.ZoomInCallFeedback.OutputChange += (s, a) =>
+ {
+ PostStatusMessage(JToken.FromObject(
+ new
+ {
+ inCall = a.BoolValue,
+ }));
+ };
+ }
+
+ private void SendFullStatus()
+ {
+ var message = new TswZoomStateMessage
+ {
+ InCall = _zoomControl?.ZoomInCallFeedback.BoolValue,
+ IncomingCall = _zoomControl?.ZoomIncomingCallFeedback.BoolValue
+ };
+
+ PostStatusMessage(message);
+ }
+ }
+
+ public class TswZoomStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("inCall", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? InCall { get; set; }
+
+ [JsonProperty("incomingCall", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IncomingCall { get; set; }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/Touchpanel/MobileControlTouchpanelController.cs b/4-series/epi-essentials-mobile-control/Touchpanel/MobileControlTouchpanelController.cs
new file mode 100644
index 0000000..705269f
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/Touchpanel/MobileControlTouchpanelController.cs
@@ -0,0 +1,513 @@
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.UI;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.DeviceInfo;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.UI;
+using PepperDash.Essentials.Touchpanel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Feedback = PepperDash.Essentials.Core.Feedback;
+
+namespace PepperDash.Essentials.Devices.Common.TouchPanel
+{
+ //public interface IMobileControlTouchpanelController
+ //{
+ // StringFeedback AppUrlFeedback { get; }
+ // string DefaultRoomKey { get; }
+ // string DeviceKey { get; }
+ //}
+
+
+ public class MobileControlTouchpanelController : TouchpanelBase, IHasFeedback, ITswAppControl, ITswZoomControl, IDeviceInfoProvider, IMobileControlTouchpanelController
+ {
+ private readonly MobileControlTouchpanelProperties localConfig;
+ private IMobileControlRoomMessenger _bridge;
+
+ private string _appUrl;
+
+ public StringFeedback AppUrlFeedback { get; private set; }
+ private readonly StringFeedback QrCodeUrlFeedback;
+ private readonly StringFeedback McServerUrlFeedback;
+ private readonly StringFeedback UserCodeFeedback;
+
+ private readonly BoolFeedback _appOpenFeedback;
+
+ public BoolFeedback AppOpenFeedback => _appOpenFeedback;
+
+ private readonly BoolFeedback _zoomIncomingCallFeedback;
+
+ public BoolFeedback ZoomIncomingCallFeedback => _zoomIncomingCallFeedback;
+
+ private readonly BoolFeedback _zoomInCallFeedback;
+
+ public event DeviceInfoChangeHandler DeviceInfoChanged;
+
+ public BoolFeedback ZoomInCallFeedback => _zoomInCallFeedback;
+
+
+ public FeedbackCollection Feedbacks { get; private set; }
+
+ public FeedbackCollection ZoomFeedbacks { get; private set; }
+
+ public string DefaultRoomKey => _config.DefaultRoomKey;
+
+ public bool UseDirectServer => localConfig.UseDirectServer;
+
+ public bool ZoomRoomController => localConfig.ZoomRoomController;
+
+ public DeviceInfo DeviceInfo => new DeviceInfo();
+
+ public MobileControlTouchpanelController(string key, string name, BasicTriListWithSmartObject panel, MobileControlTouchpanelProperties config) : base(key, name, panel, config)
+ {
+ localConfig = config;
+
+ AddPostActivationAction(SubscribeForMobileControlUpdates);
+
+ AppUrlFeedback = new StringFeedback(() => _appUrl);
+ QrCodeUrlFeedback = new StringFeedback(() => _bridge?.QrCodeUrl);
+ McServerUrlFeedback = new StringFeedback(() => _bridge?.McServerUrl);
+ UserCodeFeedback = new StringFeedback(() => _bridge?.UserCode);
+
+ _appOpenFeedback = new BoolFeedback($"{Key}-appOpen", () =>
+ {
+ if (Panel is TswX60BaseClass tsX60)
+ {
+ Debug.Console(2, this, $"x60 sending {tsX60.ExtenderApplicationControlReservedSigs.HideOpenApplicationFeedback.BoolValue}");
+ return !tsX60.ExtenderApplicationControlReservedSigs.HideOpenApplicationFeedback.BoolValue;
+ }
+
+ if (Panel is TswX70Base tsX70)
+ {
+ Debug.Console(2, this, $"x70 sending {tsX70.ExtenderApplicationControlReservedSigs.HideOpenedApplicationFeedback.BoolValue}");
+ return !tsX70.ExtenderApplicationControlReservedSigs.HideOpenedApplicationFeedback.BoolValue;
+ }
+
+ return false;
+ });
+
+ _zoomIncomingCallFeedback = new BoolFeedback($"{Key}-zoomIncomingCall", () =>
+ {
+ if (Panel is TswX60WithZoomRoomAppReservedSigs tsX60)
+ {
+ return tsX60.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.BoolValue;
+ }
+
+ if (Panel is TswX70Base tsX70)
+ {
+ return tsX70.ExtenderZoomRoomAppReservedSigs.ZoomRoomIncomingCallFeedback.BoolValue;
+ }
+
+ return false;
+ });
+
+ _zoomInCallFeedback = new BoolFeedback($"{Key}-zoomInCall", () =>
+ {
+ if (Panel is TswX60WithZoomRoomAppReservedSigs tsX60)
+ {
+ return tsX60.ExtenderZoomRoomAppReservedSigs.ZoomRoomActiveFeedback.BoolValue;
+ }
+
+ if (Panel is TswX70Base tsX70)
+ {
+ return tsX70.ExtenderZoomRoomAppReservedSigs.ZoomRoomActiveFeedback.BoolValue;
+ }
+
+ return false;
+ });
+
+ Feedbacks = new FeedbackCollection
+ {
+ AppUrlFeedback, QrCodeUrlFeedback, McServerUrlFeedback, UserCodeFeedback
+ };
+
+ ZoomFeedbacks = new FeedbackCollection {
+ AppOpenFeedback, _zoomInCallFeedback, _zoomIncomingCallFeedback
+ };
+
+ RegisterForExtenders();
+ }
+
+ private void RegisterForExtenders()
+ {
+ if (Panel is TswXX70Base x70Panel)
+ {
+ x70Panel.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) =>
+ {
+ Debug.Console(2, this, $"X70 App Control Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
+ UpdateZoomFeedbacks();
+
+ if (!x70Panel.ExtenderApplicationControlReservedSigs.HideOpenedApplicationFeedback.BoolValue)
+ {
+ x70Panel.ExtenderButtonToolbarReservedSigs.ShowButtonToolbar();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button2On();
+ } else
+ {
+ x70Panel.ExtenderButtonToolbarReservedSigs.HideButtonToolbar();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button2Off();
+ }
+ };
+
+
+ x70Panel.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) =>
+ {
+ Debug.Console(2, this, $"X70 Zoom Room Ap Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
+ UpdateZoomFeedbacks();
+ };
+
+
+ x70Panel.ExtenderEthernetReservedSigs.DeviceExtenderSigChange += (e, a) =>
+ {
+ DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
+ DeviceInfo.IpAddress = x70Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
+
+ Debug.Console(1, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
+
+ var handler = DeviceInfoChanged;
+
+ if(handler == null)
+ {
+ return;
+ }
+
+ handler(this, new DeviceInfoEventArgs(DeviceInfo));
+ };
+
+ x70Panel.ExtenderApplicationControlReservedSigs.Use();
+ x70Panel.ExtenderZoomRoomAppReservedSigs.Use();
+ x70Panel.ExtenderEthernetReservedSigs.Use();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Use();
+
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button1Off();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button3Off();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button4Off();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button5Off();
+ x70Panel.ExtenderButtonToolbarReservedSigs.Button6Off();
+
+ return;
+ }
+
+ if (Panel is TswX60WithZoomRoomAppReservedSigs x60withZoomApp)
+ {
+ x60withZoomApp.ExtenderApplicationControlReservedSigs.DeviceExtenderSigChange += (e, a) =>
+ {
+ Debug.Console(2, this, $"X60 App Control Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
+ UpdateZoomFeedbacks();
+ };
+ x60withZoomApp.ExtenderZoomRoomAppReservedSigs.DeviceExtenderSigChange += (e, a) =>
+ {
+ Debug.Console(2, this, $"X60 Zoom Room App Device Extender args: {a.Event}:{a.Sig}:{a.Sig.Type}:{a.Sig.BoolValue}:{a.Sig.UShortValue}:{a.Sig.StringValue}");
+ UpdateZoomFeedbacks();
+ };
+
+ x60withZoomApp.ExtenderEthernetReservedSigs.DeviceExtenderSigChange += (e, a) =>
+ {
+ DeviceInfo.MacAddress = x60withZoomApp.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
+ DeviceInfo.IpAddress = x60withZoomApp.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
+
+ Debug.Console(1, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
+
+ var handler = DeviceInfoChanged;
+
+ if (handler == null)
+ {
+ return;
+ }
+
+ handler(this, new DeviceInfoEventArgs(DeviceInfo));
+ };
+
+ x60withZoomApp.ExtenderZoomRoomAppReservedSigs.Use();
+ x60withZoomApp.ExtenderApplicationControlReservedSigs.Use();
+ x60withZoomApp.ExtenderEthernetReservedSigs.Use();
+ }
+ }
+
+ public override bool CustomActivate()
+ {
+ if (!(Panel is TswXX70Base) && !(Panel is TswX60WithZoomRoomAppReservedSigs))
+ {
+ return base.CustomActivate();
+ }
+ var appMessenger = new ITswAppControlMessenger($"appControlMessenger-{Key}", $"/device/{Key}", this);
+
+ var zoomMessenger = new ITswZoomControlMessenger($"zoomControlMessenger-{Key}", $"/device/{Key}", this);
+
+ var mc = DeviceManager.AllDevices.OfType().FirstOrDefault();
+
+ if (mc == null)
+ {
+ return base.CustomActivate();
+ }
+
+ mc.AddDeviceMessenger(appMessenger);
+ mc.AddDeviceMessenger(zoomMessenger);
+
+ return base.CustomActivate();
+ }
+
+
+ protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
+ {
+ Debug.Console(2, this, $"System Device Extender args: ${args.Event}:${args.Sig}");
+ }
+
+ protected override void SetupPanelDrivers(string roomKey)
+ {
+ AppUrlFeedback.LinkInputSig(Panel.StringInput[1]);
+ QrCodeUrlFeedback.LinkInputSig(Panel.StringInput[2]);
+ McServerUrlFeedback.LinkInputSig(Panel.StringInput[3]);
+ UserCodeFeedback.LinkInputSig(Panel.StringInput[4]);
+
+ Panel.OnlineStatusChange += (sender, args) =>
+ {
+ UpdateFeedbacks();
+
+ Panel.StringInput[1].StringValue = AppUrlFeedback.StringValue;
+ Panel.StringInput[2].StringValue = QrCodeUrlFeedback.StringValue;
+ Panel.StringInput[3].StringValue = McServerUrlFeedback.StringValue;
+ Panel.StringInput[4].StringValue = UserCodeFeedback.StringValue;
+ };
+ }
+
+ private void SubscribeForMobileControlUpdates()
+ {
+ foreach (var dev in DeviceManager.AllDevices)
+ {
+ Debug.Console(0, this, $"{dev.Key}:{dev.GetType().Name}");
+ }
+
+ var mcList = DeviceManager.AllDevices.OfType().ToList();
+
+ if (mcList.Count == 0)
+ {
+ Debug.Console(0, this, $"No Mobile Control controller found");
+
+ return;
+ }
+
+ // use first in list, since there should only be one.
+ var mc = mcList[0];
+
+ var bridge = mc.GetRoomBridge(_config.DefaultRoomKey);
+
+ if (bridge == null)
+ {
+ Debug.Console(0, this, $"No Mobile Control bridge for {_config.DefaultRoomKey} found ");
+ return;
+ }
+
+ _bridge = bridge;
+
+ _bridge.UserCodeChanged += UpdateFeedbacks;
+ _bridge.AppUrlChanged += (s, a) => { Debug.Console(0, this, "AppURL changed"); UpdateFeedbacks(s, a); };
+ }
+
+ public void SetAppUrl(string url)
+ {
+ _appUrl = url;
+ AppUrlFeedback.FireUpdate();
+ }
+
+ private void UpdateFeedbacks(object sender, EventArgs args)
+ {
+ UpdateFeedbacks();
+ }
+
+ private void UpdateFeedbacks()
+ {
+ foreach (var feedback in Feedbacks) { feedback.FireUpdate(); }
+ }
+
+ private void UpdateZoomFeedbacks()
+ {
+ foreach (var feedback in ZoomFeedbacks)
+ {
+ Debug.Console(1, this, $"Updating {feedback.Key}");
+ feedback.FireUpdate();
+ }
+ }
+
+ public void HideOpenApp()
+ {
+ if (Panel is TswX70Base x70Panel)
+ {
+ x70Panel.ExtenderApplicationControlReservedSigs.HideOpenedApplication();
+ return;
+ }
+
+ if (Panel is TswX60BaseClass x60Panel)
+ {
+ x60Panel.ExtenderApplicationControlReservedSigs.HideOpenApplication();
+ return;
+ }
+ }
+
+ public void OpenApp()
+ {
+ if (Panel is TswX70Base x70Panel)
+ {
+ x70Panel.ExtenderApplicationControlReservedSigs.OpenApplication();
+ return;
+ }
+
+ if (Panel is TswX60WithZoomRoomAppReservedSigs)
+ {
+ Debug.Console(0, this, $"X60 panel does not support zoom app");
+ return;
+ }
+ }
+
+ public void CloseOpenApp()
+ {
+ if (Panel is TswX70Base x70Panel)
+ {
+ x70Panel.ExtenderApplicationControlReservedSigs.CloseOpenedApplication();
+ return;
+ }
+
+ if (Panel is TswX60WithZoomRoomAppReservedSigs x60Panel)
+ {
+ x60Panel.ExtenderApplicationControlReservedSigs.CloseOpenedApplication();
+ return;
+ }
+ }
+
+ public void EndZoomCall()
+ {
+ if (Panel is TswX70Base x70Panel)
+ {
+ x70Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomEndCall();
+ return;
+ }
+
+ if (Panel is TswX60WithZoomRoomAppReservedSigs x60Panel)
+ {
+ x60Panel.ExtenderZoomRoomAppReservedSigs.ZoomRoomEndCall();
+ return;
+ }
+ }
+
+ public void UpdateDeviceInfo()
+ {
+ if (Panel is TswXX70Base x70Panel)
+ {
+ DeviceInfo.MacAddress = x70Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
+ DeviceInfo.IpAddress = x70Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
+
+ var handler = DeviceInfoChanged;
+
+ if (handler == null)
+ {
+ return;
+ }
+
+ handler(this, new DeviceInfoEventArgs(DeviceInfo));
+ }
+
+ if (Panel is TswX60WithZoomRoomAppReservedSigs x60Panel)
+ {
+ DeviceInfo.MacAddress = x60Panel.ExtenderEthernetReservedSigs.MacAddressFeedback.StringValue;
+ DeviceInfo.IpAddress = x60Panel.ExtenderEthernetReservedSigs.IpAddressFeedback.StringValue;
+
+ var handler = DeviceInfoChanged;
+
+ if (handler == null)
+ {
+ return;
+ }
+
+ handler(this, new DeviceInfoEventArgs(DeviceInfo));
+ }
+
+ Debug.Console(1, this, $"MAC: {DeviceInfo.MacAddress} IP: {DeviceInfo.IpAddress}");
+ }
+ }
+
+ public class MobileControlTouchpanelControllerFactory : EssentialsPluginDeviceFactory
+ {
+ public MobileControlTouchpanelControllerFactory()
+ {
+ TypeNames = new List() { "mccrestronapp", "mctsw550", "mctsw750", "mctsw1050", "mctsw560", "mctsw760", "mctsw1060", "mctsw570", "mctsw770", "mcts770", "mctsw1070", "mcts1070", "mcxpanel" };
+ MinimumEssentialsFrameworkVersion = "2.0.0";
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ var comm = CommFactory.GetControlPropertiesConfig(dc);
+ var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
+
+ var panel = GetPanelForType(dc.Type, comm.IpIdInt, props.ProjectName);
+
+ if (panel == null)
+ {
+ Debug.Console(0, "Unable to create Touchpanel for type {0}. Touchpanel Controller WILL NOT function correctly", dc.Type);
+ }
+
+ Debug.Console(1, "Factory Attempting to create new MobileControlTouchpanelController");
+
+ var panelController = new MobileControlTouchpanelController(dc.Key, dc.Name, panel, props);
+
+ return panelController;
+ }
+
+ private BasicTriListWithSmartObject GetPanelForType(string type, uint id, string projectName)
+ {
+ type = type.ToLower().Replace("mc", "");
+ try
+ {
+ if (type == "crestronapp")
+ {
+ var app = new CrestronApp(id, Global.ControlSystem);
+ app.ParameterProjectName.Value = projectName;
+ return app;
+ }
+ else if (type == "xpanel")
+ return new XpanelForHtml5(id, Global.ControlSystem);
+ else if (type == "tsw550")
+ return new Tsw550(id, Global.ControlSystem);
+ else if (type == "tsw552")
+ return new Tsw552(id, Global.ControlSystem);
+ else if (type == "tsw560")
+ return new Tsw560(id, Global.ControlSystem);
+ else if (type == "tsw750")
+ return new Tsw750(id, Global.ControlSystem);
+ else if (type == "tsw752")
+ return new Tsw752(id, Global.ControlSystem);
+ else if (type == "tsw760")
+ return new Tsw760(id, Global.ControlSystem);
+ else if (type == "tsw1050")
+ return new Tsw1050(id, Global.ControlSystem);
+ else if (type == "tsw1052")
+ return new Tsw1052(id, Global.ControlSystem);
+ else if (type == "tsw1060")
+ return new Tsw1060(id, Global.ControlSystem);
+ else if (type == "tsw570")
+ return new Tsw570(id, Global.ControlSystem);
+ else if (type == "tsw770")
+ return new Tsw770(id, Global.ControlSystem);
+ else if (type == "ts770")
+ return new Ts770(id, Global.ControlSystem);
+ else if (type == "tsw1070")
+ return new Tsw1070(id, Global.ControlSystem);
+ else if (type == "ts1070")
+ return new Ts1070(id, Global.ControlSystem);
+ else
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
+ return null;
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
+ return null;
+ }
+ }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/Touchpanel/MobileControlTouchpanelProperties.cs b/4-series/epi-essentials-mobile-control/Touchpanel/MobileControlTouchpanelProperties.cs
new file mode 100644
index 0000000..a72eaa6
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/Touchpanel/MobileControlTouchpanelProperties.cs
@@ -0,0 +1,17 @@
+using Newtonsoft.Json;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.Devices.Common.TouchPanel
+{
+ public class MobileControlTouchpanelProperties : CrestronTouchpanelPropertiesConfig
+ {
+ [JsonProperty("useDirectServer")]
+ public bool UseDirectServer { get; set; } = false;
+
+ [JsonProperty("zoomRoomController")]
+ public bool ZoomRoomController { get; set; } = false;
+
+ [JsonProperty("buttonToolbarTimeoutInS")]
+ public ushort ButtonToolbarTimoutInS { get; set; } = 0;
+ }
+}
\ No newline at end of file
diff --git a/4-series/epi-essentials-mobile-control/UserCodeChangedContent.cs b/4-series/epi-essentials-mobile-control/UserCodeChangedContent.cs
new file mode 100644
index 0000000..ef00442
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/UserCodeChangedContent.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials.AppServer
+{
+ public class UserCodeChangedContent
+ {
+ [JsonProperty("userCode")]
+ public string UserCode { get; set; }
+
+ [JsonProperty("qrChecksum", NullValueHandling = NullValueHandling.Include)]
+ public string QrChecksum { get; set; }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/WebApiHandlers/ActionPathsHandler.cs b/4-series/epi-essentials-mobile-control/WebApiHandlers/ActionPathsHandler.cs
new file mode 100644
index 0000000..7351cc1
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/WebApiHandlers/ActionPathsHandler.cs
@@ -0,0 +1,52 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.AppServer.Messengers;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace PepperDash.Essentials.WebApiHandlers
+{
+ public class ActionPathsHandler : WebApiBaseRequestHandler
+ {
+ private readonly MobileControlSystemController mcController;
+ public ActionPathsHandler(MobileControlSystemController controller) : base(true)
+ {
+ mcController = controller;
+ }
+
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var response = JsonConvert.SerializeObject(new ActionPathsResponse(mcController));
+
+ context.Response.StatusCode = 200;
+ context.Response.ContentType = "application/json";
+ context.Response.Headers.Add("Content-Type", "application/json");
+ context.Response.Write(response, false);
+ context.Response.End();
+ }
+ }
+
+ public class ActionPathsResponse
+ {
+ [JsonIgnore]
+ private readonly MobileControlSystemController mcController;
+
+ [JsonProperty("actionPaths")]
+ public List ActionPaths => mcController.GetActionDictionaryPaths().Select((path) => new ActionPath { MessengerKey = path.Item1, Path = path.Item2}).ToList();
+
+ public ActionPathsResponse(MobileControlSystemController mcController)
+ {
+ this.mcController = mcController;
+ }
+ }
+
+ public class ActionPath
+ {
+ [JsonProperty("messengerKey")]
+ public string MessengerKey { get; set; }
+
+ [JsonProperty("path")]
+ public string Path { get; set; }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/WebApiHandlers/MobileAuthRequestHandler.cs b/4-series/epi-essentials-mobile-control/WebApiHandlers/MobileAuthRequestHandler.cs
new file mode 100644
index 0000000..2dc8407
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/WebApiHandlers/MobileAuthRequestHandler.cs
@@ -0,0 +1,64 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.Core.Web;
+using System;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.WebApiHandlers
+{
+ public class MobileAuthRequestHandler : WebApiBaseRequestAsyncHandler
+ {
+ private readonly MobileControlSystemController mcController;
+
+ public MobileAuthRequestHandler(MobileControlSystemController controller) : base(true)
+ {
+ mcController = controller;
+ }
+
+ protected override async Task HandlePost(HttpCwsContext context)
+ {
+ var requestBody = EssentialsWebApiHelpers.GetRequestBody(context.Request);
+
+ var grantCode = JsonConvert.DeserializeObject(requestBody);
+
+ if (string.IsNullOrEmpty(grantCode?.GrantCode))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Missing grant code";
+ context.Response.End();
+ return;
+ }
+
+ var response = await mcController.ApiService.SendAuthorizationRequest(mcController.Host, grantCode.GrantCode, mcController.SystemUuid);
+
+ Debug.Console(1, $"response received");
+ if (response.Authorized)
+ {
+ mcController.RegisterSystemToServer();
+ }
+
+ try
+ {
+ context.Response.StatusCode = 200;
+ var responseBody = JsonConvert.SerializeObject(response, Formatting.None);
+ context.Response.ContentType = "application/json";
+ context.Response.Headers.Add("Content-Type", "application/json");
+ context.Response.Write(responseBody, false);
+ context.Response.End();
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, $"Exception handling MC Auth request: {ex.Message}");
+ Debug.Console(2, $"Stack Trace: {ex.StackTrace}");
+
+ if (ex.InnerException != null)
+ {
+ Debug.Console(0, $"Inner Exception: {ex.InnerException.Message}");
+ Debug.Console(2, $"Inner Exception Stack Trace: {ex.InnerException.StackTrace}");
+ }
+ }
+ }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/WebApiHandlers/MobileInfoHandler.cs b/4-series/epi-essentials-mobile-control/WebApiHandlers/MobileInfoHandler.cs
new file mode 100644
index 0000000..f0c1809
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/WebApiHandlers/MobileInfoHandler.cs
@@ -0,0 +1,159 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.Core.Config;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace PepperDash.Essentials.WebApiHandlers
+{
+ public class MobileInfoHandler : WebApiBaseRequestHandler
+ {
+ private readonly MobileControlSystemController mcController;
+ public MobileInfoHandler(MobileControlSystemController controller) : base(true)
+ {
+ mcController = controller;
+ }
+
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ try
+ {
+ var response = new InformationResponse(mcController);
+
+ context.Response.StatusCode = 200;
+ context.Response.ContentType = "application/json";
+ context.Response.Write(JsonConvert.SerializeObject(response), false);
+ context.Response.End();
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(1, $"exception showing mobile info: {ex.Message}");
+ Debug.Console(2, $"stack trace: {ex.StackTrace}");
+
+ context.Response.StatusCode = 500;
+ context.Response.End();
+ }
+ }
+ }
+
+ public class InformationResponse
+ {
+ [JsonIgnore]
+ private readonly MobileControlSystemController mcController;
+
+ [JsonProperty("edgeServer", NullValueHandling = NullValueHandling.Ignore)]
+ public MobileControlEdgeServer EdgeServer => mcController.Config.EnableApiServer ? new MobileControlEdgeServer(mcController) : null;
+
+
+ [JsonProperty("directServer", NullValueHandling = NullValueHandling.Ignore)]
+ public MobileControlDirectServer DirectServer => mcController.Config.DirectServer.EnableDirectServer ? new MobileControlDirectServer(mcController.DirectServer) : null;
+
+
+ public InformationResponse(MobileControlSystemController controller)
+ {
+ mcController = controller;
+ }
+ }
+
+ public class MobileControlEdgeServer
+ {
+ [JsonIgnore]
+ private readonly MobileControlSystemController mcController;
+
+ [JsonProperty("serverAddress")]
+ public string ServerAddress => mcController.Config == null ? "No Config" : mcController.Host;
+
+ [JsonProperty("systemName")]
+ public string SystemName => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].RoomName : "No Config";
+
+ [JsonProperty("systemUrl")]
+ public string SystemUrl => ConfigReader.ConfigObject.SystemUrl;
+
+ [JsonProperty("userCode")]
+ public string UserCode => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].UserCode : "Not available";
+
+ [JsonProperty("connected")]
+ public bool Connected => mcController.Connected;
+
+ [JsonProperty("secondsSinceLastAck")]
+ public int SecondsSinceLastAck => (DateTime.Now - mcController.LastAckMessage).Seconds;
+
+ public MobileControlEdgeServer(MobileControlSystemController controller)
+ {
+ mcController = controller;
+ }
+ }
+
+ public class MobileControlDirectServer
+ {
+ [JsonIgnore]
+ private readonly MobileControlWebsocketServer directServer;
+
+ [JsonProperty("userAppUrl")]
+ public string UserAppUrl => $"{directServer.UserAppUrlPrefix}/[insert_client_token]";
+
+ [JsonProperty("serverPort")]
+ public int ServerPort => directServer.Port;
+
+ [JsonProperty("tokensDefined")]
+ public int TokensDefined => directServer.UiClients.Count;
+
+ [JsonProperty("clientsConnected")]
+ public int ClientsConnected => directServer.ConnectedUiClientsCount;
+
+ [JsonProperty("clients")]
+ public List Clients => directServer.UiClients.Select((c, i) => { return new MobileControlDirectClient(c, i, directServer.UserAppUrlPrefix); }).ToList();
+
+ public MobileControlDirectServer(MobileControlWebsocketServer server)
+ {
+ directServer = server;
+ }
+ }
+
+ public class MobileControlDirectClient
+ {
+ [JsonIgnore]
+ private readonly UiClientContext context;
+
+ [JsonIgnore]
+ private readonly string Key;
+
+ [JsonIgnore]
+ private readonly int clientNumber;
+
+ [JsonIgnore]
+ private readonly string urlPrefix;
+
+ [JsonProperty("clientNumber")]
+ public string ClientNumber => $"{clientNumber}";
+
+ [JsonProperty("roomKey")]
+ public string RoomKey => context.Token.RoomKey;
+
+ [JsonProperty("touchpanelKey")]
+ public string TouchpanelKey => context.Token.TouchpanelKey;
+
+ [JsonProperty("url")]
+ public string Url => $"{urlPrefix}{Key}";
+
+ [JsonProperty("token")]
+ public string Token => Key;
+
+ [JsonProperty("connected")]
+ public bool Connected => context.Client == null ? false : context.Client.Context.WebSocket.IsAlive;
+
+ [JsonProperty("duration")]
+ public double Duration => context.Client == null ? 0 : context.Client.ConnectedDuration.TotalSeconds;
+
+ public MobileControlDirectClient(KeyValuePair clientContext, int index, string urlPrefix)
+ {
+ context = clientContext.Value;
+ Key = clientContext.Key;
+ clientNumber = index;
+ this.urlPrefix = urlPrefix;
+ }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/WebApiHandlers/UiClientHandler.cs b/4-series/epi-essentials-mobile-control/WebApiHandlers/UiClientHandler.cs
new file mode 100644
index 0000000..537dafb
--- /dev/null
+++ b/4-series/epi-essentials-mobile-control/WebApiHandlers/UiClientHandler.cs
@@ -0,0 +1,164 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.Core.Web;
+
+namespace PepperDash.Essentials.WebApiHandlers
+{
+ public class UiClientHandler : WebApiBaseRequestHandler
+ {
+ private readonly MobileControlWebsocketServer server;
+ public UiClientHandler(MobileControlWebsocketServer directServer) : base(true)
+ {
+ server = directServer;
+ }
+
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ var req = context.Request;
+ var res = context.Response;
+ var body = EssentialsWebApiHelpers.GetRequestBody(req);
+
+ var request = JsonConvert.DeserializeObject(body);
+
+ var response = new ClientResponse();
+
+ if (string.IsNullOrEmpty(request?.RoomKey))
+ {
+ response.Error = "roomKey is required";
+
+ res.StatusCode = 400;
+ res.ContentType = "application/json";
+ res.Headers.Add("Content-Type", "application/json");
+ res.Write(JsonConvert.SerializeObject(response), false);
+ res.End();
+ return;
+ }
+
+ if (string.IsNullOrEmpty(request.GrantCode))
+ {
+ response.Error = "grantCode is required";
+
+ res.StatusCode = 400;
+ res.ContentType = "application/json";
+ res.Headers.Add("Content-Type", "application/json");
+ res.Write(JsonConvert.SerializeObject(response), false);
+ res.End();
+ return;
+ }
+
+ var (token, path) = server.ValidateGrantCode(request.GrantCode, request.RoomKey);
+
+ response.Token = token;
+ response.Path = path;
+
+ res.StatusCode = 200;
+ res.ContentType = "application/json";
+ res.Headers.Add("Content-Type", "application/json");
+ res.Write(JsonConvert.SerializeObject(response), false);
+ res.End();
+ }
+
+ protected override void HandleDelete(HttpCwsContext context)
+ {
+ var req = context.Request;
+ var res = context.Response;
+ var body = EssentialsWebApiHelpers.GetRequestBody(req);
+
+ var request = JsonConvert.DeserializeObject(body);
+
+
+
+ if (string.IsNullOrEmpty(request?.Token))
+ {
+ var response = new ClientResponse
+ {
+ Error = "token is required"
+ };
+
+ res.StatusCode = 400;
+ res.ContentType = "application/json";
+ res.Headers.Add("Content-Type", "application/json");
+ res.Write(JsonConvert.SerializeObject(response), false);
+ res.End();
+
+ return;
+ }
+
+
+
+ if (!server.UiClients.TryGetValue(request.Token, out UiClientContext clientContext))
+ {
+ var response = new ClientResponse
+ {
+ Error = $"Unable to find client with token: {request.Token}"
+ };
+
+ res.StatusCode = 200;
+ res.ContentType = "application/json";
+ res.Headers.Add("Content-Type", "application/json");
+ res.Write(JsonConvert.SerializeObject(response), false);
+ res.End();
+
+ return;
+ }
+
+ if (clientContext.Client != null && clientContext.Client.Context.WebSocket.IsAlive)
+ {
+ clientContext.Client.Context.WebSocket.Close(WebSocketSharp.CloseStatusCode.Normal, "Token removed from server");
+ }
+
+ var path = server.WsPath + request.Token;
+
+ if (!server.Server.RemoveWebSocketService(path))
+ {
+ Debug.Console(0, $"Unable to remove client with token {request.Token}");
+
+ var response = new ClientResponse
+ {
+ Error = $"Unable to remove client with token {request.Token}"
+ };
+
+ res.StatusCode = 500;
+ res.ContentType = "application/json";
+ res.Headers.Add("Content-Type", "application/json");
+ res.Write(JsonConvert.SerializeObject(response), false);
+ res.End();
+
+ return;
+ }
+
+ server.UiClients.Remove(request.Token);
+
+ server.UpdateSecret();
+
+ res.StatusCode = 200;
+ res.End();
+ }
+ }
+
+ public class ClientRequest
+ {
+ [JsonProperty("roomKey", NullValueHandling = NullValueHandling.Ignore)]
+ public string RoomKey { get; set; }
+
+ [JsonProperty("grantCode", NullValueHandling = NullValueHandling.Ignore)]
+ public string GrantCode { get; set; }
+
+ [JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
+ public string Token { get; set; }
+ }
+
+ public class ClientResponse
+ {
+ [JsonProperty("error", NullValueHandling = NullValueHandling.Ignore)]
+ public string Error { get; set; }
+
+ [JsonProperty("token", NullValueHandling = NullValueHandling.Ignore)]
+ public string Token { get; set; }
+
+ [JsonProperty("path", NullValueHandling = NullValueHandling.Ignore)]
+ public string Path { get; set; }
+ }
+}
diff --git a/4-series/epi-essentials-mobile-control/WebSocketServer/MobileControlWebsocketServer.cs b/4-series/epi-essentials-mobile-control/WebSocketServer/MobileControlWebsocketServer.cs
index e2fb028..b167fd6 100644
--- a/4-series/epi-essentials-mobile-control/WebSocketServer/MobileControlWebsocketServer.cs
+++ b/4-series/epi-essentials-mobile-control/WebSocketServer/MobileControlWebsocketServer.cs
@@ -1,16 +1,26 @@
using Crestron.SimplSharp;
-using Crestron.SimplSharp.CrestronIO;
+using Crestron.SimplSharp.WebScripting;
using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using PepperDash.Essentials.Core.Web;
+using PepperDash.Essentials.Devices.Common.TouchPanel;
+using PepperDash.Essentials.WebApiHandlers;
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using WebSocketSharp;
using WebSocketSharp.Net;
using WebSocketSharp.Server;
+using ErrorEventArgs = WebSocketSharp.ErrorEventArgs;
+
namespace PepperDash.Essentials
{
@@ -18,7 +28,7 @@ namespace PepperDash.Essentials
/// Represents the behaviour to associate with a UiClient for WebSocket communication
///
public class UiClient : WebSocketBehavior
- {
+ {
public MobileControlSystemController Controller { get; set; }
public string RoomKey { get; set; }
@@ -42,8 +52,8 @@ public TimeSpan ConnectedDuration
public UiClient()
{
-
- }
+
+ }
protected override void OnOpen()
{
@@ -56,12 +66,12 @@ protected override void OnOpen()
if (match.Success)
{
- var clientId = match.Groups[1].Value;
-
+ var clientId = match.Groups[1].Value;
+
// Inform controller of client joining
if (Controller != null)
{
- var clientJoined = new MobileControlResponseMessage
+ var clientJoined = new MobileControlMessage
{
Type = "/system/roomKey",
ClientId = clientId,
@@ -88,18 +98,18 @@ protected override void OnOpen()
}
private void SendUserCodeToClient(MobileControlBridgeBase bridge, string clientId)
- {
+ {
var content = new
{
userCode = bridge.UserCode,
qrUrl = bridge.QrCodeUrl,
};
- var message = new MobileControlResponseMessage
+ var message = new MobileControlMessage
{
- Type = "/system/userCodeChanged",
+ Type = "/system/userCodeChanged",
ClientId = clientId,
- Content = content
+ Content = JToken.FromObject(content)
};
Controller.SendMessageObjectToDirectClient(message);
@@ -134,11 +144,11 @@ protected override void OnError(ErrorEventArgs e)
public class MobileControlWebsocketServer : EssentialsDevice
{
- private string userAppPath = Global.FilePathPrefix + "mcUserApp" + Global.DirectorySeparator;
+ private readonly string userAppPath = Global.FilePathPrefix + "mcUserApp" + Global.DirectorySeparator;
- private string localConfigFolderName = "_local-config";
+ private readonly string localConfigFolderName = "_local-config";
- private string appConfigFileName = "_config.local.json";
+ private readonly string appConfigFileName = "_config.local.json";
///
/// Where the key is the join token and the value is the room key
@@ -147,17 +157,19 @@ public class MobileControlWebsocketServer : EssentialsDevice
private HttpServer _server;
+ public HttpServer Server => _server;
+
public Dictionary UiClients { get; private set; }
- private MobileControlSystemController _parent;
+ private readonly MobileControlSystemController _parent;
private WebSocketServerSecretProvider _secretProvider;
private ServerTokenSecrets _secret;
- private static HttpClient LogClient = new HttpClient();
+ private static readonly HttpClient LogClient = new HttpClient();
- private string _secretProviderKey
+ private string SecretProviderKey
{
get
{
@@ -168,12 +180,14 @@ private string _secretProviderKey
///
/// The path for the WebSocket messaging
///
- private string _wsPath = "/mc/api/ui/join/";
+ private readonly string _wsPath = "/mc/api/ui/join/";
+
+ public string WsPath => _wsPath;
///
/// The path to the location of the files for the user app (single page Angular app)
///
- private string _appPath = string.Format("{0}mcUserApp", Global.FilePathPrefix);
+ private readonly string _appPath = string.Format("{0}mcUserApp", Global.FilePathPrefix);
///
/// The base HREF that the user app uses
@@ -185,7 +199,7 @@ private string _secretProviderKey
///
public int Port { get; private set; }
- public string UserAppUrlPrefix
+ public string UserAppUrlPrefix
{
get
{
@@ -214,7 +228,7 @@ public int ConnectedUiClientsCount
return count;
}
}
-
+
public MobileControlWebsocketServer(string key, int customPort, MobileControlSystemController parent)
: base(key)
{
@@ -232,7 +246,39 @@ public MobileControlWebsocketServer(string key, int customPort, MobileControlSys
//_joinTokens = new Dictionary();
- CrestronConsole.AddNewConsoleCommand(GenerateClientToken, "MobileAddUiClient", "Adds a client and generates a token. ? for more help", ConsoleAccessLevelEnum.AccessOperator);
+ if (Global.Platform == eDevicePlatform.Appliance)
+ {
+ AddConsoleCommands();
+ }
+
+ AddPreActivationAction(() => AddWebApiPaths());
+ }
+
+ private void AddWebApiPaths()
+ {
+ var apiServer = DeviceManager.AllDevices.OfType().FirstOrDefault();
+
+ if (apiServer == null)
+ {
+ Debug.Console(0, this, "No API Server available");
+ return;
+ }
+
+ var routes = new List
+ {
+ new HttpCwsRoute($"devices/{Key}/client")
+ {
+ Name = "ClientHandler",
+ RouteHandler = new UiClientHandler(this)
+ },
+ };
+
+ apiServer.AddRoute(routes);
+ }
+
+ private void AddConsoleCommands()
+ {
+ CrestronConsole.AddNewConsoleCommand(GenerateClientTokenFromConsole, "MobileAddUiClient", "Adds a client and generates a token. ? for more help", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(RemoveToken, "MobileRemoveUiClient", "Removes a client. ? for more help", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand((s) => PrintClientInfo(), "MobileGetClientInfo", "Displays the current client info", ConsoleAccessLevelEnum.AccessOperator);
}
@@ -250,7 +296,7 @@ public override void Initialize()
if (_parent.Config.DirectServer.Logging.EnableRemoteLogging)
{
- _server.OnPost += Server_OnPost;
+ _server.OnPost += Server_OnPost;
}
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
@@ -267,6 +313,69 @@ public override void Initialize()
RetrieveSecret();
CreateFolderStructure();
+
+ AddClientsForTouchpanels();
+ }
+
+ private void AddClientsForTouchpanels()
+ {
+ var touchpanels = DeviceManager.AllDevices
+ .OfType().Where(tp => tp.UseDirectServer);
+
+
+ var newTouchpanels = touchpanels.Where(tp => !_secret.Tokens.Any(t => t.Value.TouchpanelKey != null && t.Value.TouchpanelKey.Equals(tp.Key, StringComparison.InvariantCultureIgnoreCase)));
+
+
+ foreach (var client in newTouchpanels)
+ {
+ var bridge = _parent.GetRoomBridge(client.DefaultRoomKey);
+
+ if (bridge == null)
+ {
+ Debug.Console(0, this, $"Unable to find room with key: {client.DefaultRoomKey}");
+ return;
+ }
+
+ var (key, path) = GenerateClientToken(bridge, client.Key);
+
+ if (key == null)
+ {
+ Debug.Console(0, this, $"Unable to generate a client for {client.Key}");
+ continue;
+ }
+ }
+
+ foreach (var touchpanel in touchpanels.Select(tp =>
+ {
+ var token = _secret.Tokens.FirstOrDefault((t) => t.Value.TouchpanelKey.Equals(tp.Key, StringComparison.InvariantCultureIgnoreCase));
+
+ var messenger = _parent.GetRoomBridge(tp.DefaultRoomKey);
+
+ return new { token.Key, Touchpanel = tp, Messenger = messenger };
+ }))
+ {
+ if (touchpanel.Key == null)
+ {
+ Debug.Console(0, this, $"Token for touchpanel {touchpanel.Touchpanel.Key} not found");
+ continue;
+ }
+
+ if (touchpanel.Messenger == null)
+ {
+ Debug.Console(2, this, $"Unable to find room messenger for {touchpanel.Touchpanel.DefaultRoomKey}");
+ continue;
+ }
+
+ var lanAdapterId = CrestronEthernetHelper.GetAdapterdIdForSpecifiedAdapterType(EthernetAdapterType.EthernetLANAdapter);
+
+ var processorIp = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, lanAdapterId);
+
+ var appUrl = $"http://{processorIp}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}";
+
+ Debug.Console(2, this, $"Sending URL {appUrl}");
+
+ touchpanel.Messenger.UpdateAppUrl($"http://{processorIp}:{_parent.Config.DirectServer.Port}/mc/app?token={touchpanel.Key}");
+ }
}
private void OnProgramStop(eProgramStatusEventType programEventType)
@@ -275,22 +384,23 @@ private void OnProgramStop(eProgramStatusEventType programEventType)
{
case eProgramStatusEventType.Stopping:
_server.Stop();
- break;
+ break;
}
}
private void CreateFolderStructure()
{
- if (!Directory.Exists(userAppPath)) {
- Directory.Create(userAppPath);
+ if (!Directory.Exists(userAppPath))
+ {
+ Directory.CreateDirectory(userAppPath);
}
if (!Directory.Exists($"{userAppPath}{localConfigFolderName}"))
{
- Directory.Create($"{userAppPath}{localConfigFolderName}");
+ Directory.CreateDirectory($"{userAppPath}{localConfigFolderName}");
}
- using(var sw = new StreamWriter(File.Open($"{userAppPath}{localConfigFolderName}{Global.DirectorySeparator}{appConfigFileName}", FileMode.Truncate, FileAccess.ReadWrite)))
+ using (var sw = new StreamWriter(File.Open($"{userAppPath}{localConfigFolderName}{Global.DirectorySeparator}{appConfigFileName}", FileMode.Create, FileAccess.ReadWrite)))
{
var config = GetApplicationConfig();
@@ -331,7 +441,7 @@ private MobileControlApplicationConfig GetApplicationConfig()
}
}
},
- Logging = _parent.Config.DirectServer.Logging.EnableRemoteLogging,
+ Logging = _parent.Config.DirectServer.Logging.EnableRemoteLogging,
};
}
else
@@ -358,7 +468,8 @@ private MobileControlApplicationConfig GetApplicationConfig()
Logging = _parent.Config.ApplicationConfig.Logging
};
}
- } catch(Exception ex)
+ }
+ catch (Exception ex)
{
Debug.Console(0, this, "Error getting application configuration: {0}", ex.Message);
Debug.Console(2, this, "Stack Trace: {0}", ex.StackTrace);
@@ -375,10 +486,10 @@ private MobileControlApplicationConfig GetApplicationConfig()
private void RetrieveSecret()
{
// Add secret provider
- _secretProvider = new WebSocketServerSecretProvider(_secretProviderKey);
+ _secretProvider = new WebSocketServerSecretProvider(SecretProviderKey);
// Check for existing secrets
- var secret = _secretProvider.GetSecret(_secretProviderKey);
+ var secret = _secretProvider.GetSecret(SecretProviderKey);
if (secret != null)
{
@@ -430,9 +541,8 @@ private void RetrieveSecret()
///
/// Stores secrets to memory to persist through reboot
///
- private void UpdateSecret()
+ public void UpdateSecret()
{
-
_secret.Tokens.Clear();
foreach (var uiClientContext in UiClients)
@@ -442,14 +552,14 @@ private void UpdateSecret()
var serializedSecret = JsonConvert.SerializeObject(_secret);
- _secretProvider.SetSecret(_secretProviderKey, serializedSecret);
+ _secretProvider.SetSecret(SecretProviderKey, serializedSecret);
}
///
/// Generates a new token based on validating a room key and grant code passed in. If valid, returns a token and adds a service to the server for that token's path
///
///
- private void GenerateClientToken(string s)
+ private void GenerateClientTokenFromConsole(string s)
{
if (s == "?" || string.IsNullOrEmpty(s))
{
@@ -461,58 +571,88 @@ private void GenerateClientToken(string s)
var roomKey = values[0];
var grantCode = values[1];
+ var bridge = _parent.GetRoomBridge(roomKey);
+
+ if (bridge == null)
+ {
+ CrestronConsole.ConsoleCommandResponse(string.Format("Unable to find room with key: {0}", roomKey));
+ return;
+ }
+
+ var (token, path) = ValidateGrantCode(grantCode, bridge);
+
+ if (token == null)
+ {
+ CrestronConsole.ConsoleCommandResponse("Grant Code is not valid");
+ return;
+ }
+
+ CrestronConsole.ConsoleCommandResponse($"Added new WebSocket UiClient service at path: {path}");
+ CrestronConsole.ConsoleCommandResponse($"Token: {token}");
+ }
+
+ public (string, string) ValidateGrantCode(string grantCode, string roomKey)
+ {
+ var bridge = _parent.GetRoomBridge(roomKey);
+
+ if (bridge == null)
+ {
+ Debug.Console(0, this, $"Unable to find room with key: {roomKey}");
+ return (null, null);
+ }
+
+ return ValidateGrantCode(grantCode, bridge);
+ }
+
+ public (string, string) ValidateGrantCode(string grantCode, MobileControlBridgeBase bridge)
+ {
// TODO: Authenticate grant code passed in
// For now, we just generate a random guid as the token and use it as the ClientId as well
-
var grantCodeIsValid = true;
if (grantCodeIsValid)
{
-
if (_secret == null)
{
_secret = new ServerTokenSecrets(grantCode);
}
- var bridge = _parent.GetRoomBridge(roomKey);
- if (bridge != null)
- {
- var key = Guid.NewGuid().ToString();
+ return GenerateClientToken(bridge, "");
+ }
+ else
+ {
+ return (null, null);
+ }
+ }
- var token = new JoinToken() { Code = bridge.UserCode, RoomKey = bridge.RoomKey, Uuid = _parent.SystemUuid };
+ public (string, string) GenerateClientToken(MobileControlBridgeBase bridge, string touchPanelKey = "")
+ {
+ var key = Guid.NewGuid().ToString();
- UiClients.Add(key, new UiClientContext(token));
+ var token = new JoinToken { Code = bridge.UserCode, RoomKey = bridge.RoomKey, Uuid = _parent.SystemUuid, TouchpanelKey = touchPanelKey };
- var path = _wsPath + key;
+ UiClients.Add(key, new UiClientContext(token));
- _server.AddWebSocketService(path, () =>
- {
- var c = new UiClient();
- Debug.Console(2, this, "Constructing UiClient with id: {0}", key);
- c.Controller = _parent;
- c.RoomKey = roomKey;
- UiClients[key].SetClient(c);
- return c;
- });
+ var path = _wsPath + key;
+ _server.AddWebSocketService(path, () =>
+ {
+ var c = new UiClient();
+ Debug.Console(2, this, "Constructing UiClient with id: {0}", key);
+ c.Controller = _parent;
+ c.RoomKey = bridge.RoomKey;
+ UiClients[key].SetClient(c);
+ return c;
+ });
- CrestronConsole.ConsoleCommandResponse("Added new WebSocket UiClient service at path: {0}", path);
+ Debug.Console(0, this, $"Added new WebSocket UiClient service at path: {path}");
+ Debug.Console(0, this, $"Token: {key}");
- Debug.Console(2, this, "{0} websocket services present", _server.WebSocketServices.Count);
+ Debug.Console(2, this, "{0} websocket services present", _server.WebSocketServices.Count);
- CrestronConsole.ConsoleCommandResponse(string.Format("Token: {0}", key));
+ UpdateSecret();
- UpdateSecret();
- }
- else
- {
- CrestronConsole.ConsoleCommandResponse(string.Format("Unable to find room with key: {0}", roomKey));
- }
- }
- else
- {
- CrestronConsole.ConsoleCommandResponse("Grant Code is not valid");
- }
+ return (key, path);
}
///
@@ -529,8 +669,8 @@ private void RemoveToken(string s)
var key = s;
- if(UiClients.ContainsKey(key))
- {
+ if (UiClients.ContainsKey(key))
+ {
var uiClientContext = UiClients[key];
if (uiClientContext.Client != null && uiClientContext.Client.Context.WebSocket.IsAlive)
@@ -577,7 +717,7 @@ private void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventTy
{
if (programEventType == eProgramStatusEventType.Stopping)
{
- foreach(var client in UiClients.Values)
+ foreach (var client in UiClients.Values)
{
if (client.Client != null && client.Client.Context.WebSocket.IsAlive)
{
@@ -646,13 +786,13 @@ private async void Server_OnPost(object sender, HttpRequestEventArgs e)
res.AddHeader("Access-Control-Allow-Origin", "*");
var path = req.RawUrl;
- var ip = req.RemoteEndPoint.Address.ToString();
+ var ip = req.RemoteEndPoint.Address.ToString();
- Debug.Console(2, this, "POST Request received at path: {0} from host {1}", path, ip);
+ Debug.Console(2, this, "POST Request received at path: {0} from host {1}", path, ip);
var body = new System.IO.StreamReader(req.InputStream).ReadToEnd();
- if(path.StartsWith("/mc/api/log"))
+ if (path.StartsWith("/mc/api/log"))
{
res.StatusCode = 200;
res.Close();
@@ -667,10 +807,11 @@ private async void Server_OnPost(object sender, HttpRequestEventArgs e)
await LogClient.SendAsync(logRequest);
Debug.Console(2, this, "Log data sent to {0}:{1}", _parent.Config.DirectServer.Logging.Host, _parent.Config.DirectServer.Logging.Port);
- } else
+ }
+ else
{
res.StatusCode = 404;
- res.Close();
+ res.Close();
}
}
catch (Exception ex)
@@ -678,7 +819,7 @@ private async void Server_OnPost(object sender, HttpRequestEventArgs e)
Debug.Console(0, Debug.ErrorLogLevel.Error, "Caught an exception in the OnPost handler {0}", ex.Message);
Debug.Console(2, Debug.ErrorLogLevel.Error, "StackTrace: {0}", ex.StackTrace);
- if(ex.InnerException != null)
+ if (ex.InnerException != null)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Caught an exception in the OnGet handler {0}", ex.InnerException.Message);
Debug.Console(2, Debug.ErrorLogLevel.Error, "StackTrace: {0}", ex.InnerException.StackTrace);
@@ -689,7 +830,7 @@ private async void Server_OnPost(object sender, HttpRequestEventArgs e)
private void Server_OnOptions(object sender, HttpRequestEventArgs e)
{
try
- {
+ {
var res = e.Response;
res.AddHeader("Access-Control-Allow-Origin", "*");
@@ -697,7 +838,7 @@ private void Server_OnOptions(object sender, HttpRequestEventArgs e)
res.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
res.StatusCode = 200;
- res.Close();
+ res.Close();
}
catch (Exception ex)
{
@@ -725,9 +866,8 @@ private void HandleJoinRequest(HttpListenerRequest req, HttpListenerResponse res
Debug.Console(2, this, "Join Room Request with token: {0}", token);
- UiClientContext clientContext = null;
- if (UiClients.TryGetValue(token, out clientContext))
+ if (UiClients.TryGetValue(token, out UiClientContext clientContext))
{
var bridge = _parent.GetRoomBridge(clientContext.Token.RoomKey);
@@ -737,18 +877,20 @@ private void HandleJoinRequest(HttpListenerRequest req, HttpListenerResponse res
res.ContentType = "application/json";
// Construct the response object
- JoinResponse jRes = new JoinResponse();
- jRes.ClientId = token;
- jRes.RoomKey = bridge.RoomKey;
- jRes.SystemUuid = _parent.SystemUuid;
- jRes.RoomUuid = _parent.SystemUuid;
- jRes.Config = _parent.GetConfigWithPluginVersion();
- jRes.CodeExpires = new DateTime().AddYears(1);
- jRes.UserCode = bridge.UserCode;
- jRes.UserAppUrl = string.Format("http://{0}:{1}/mc/app",
+ JoinResponse jRes = new JoinResponse
+ {
+ ClientId = token,
+ RoomKey = bridge.RoomKey,
+ SystemUuid = _parent.SystemUuid,
+ RoomUuid = _parent.SystemUuid,
+ Config = _parent.GetConfigWithPluginVersion(),
+ CodeExpires = new DateTime().AddYears(1),
+ UserCode = bridge.UserCode,
+ UserAppUrl = string.Format("http://{0}:{1}/mc/app",
CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0),
- Port);
- jRes.EnableDebug = false;
+ Port),
+ EnableDebug = false
+ };
// Serialize to JSON and convert to Byte[]
var json = JsonConvert.SerializeObject(jRes);
@@ -900,7 +1042,7 @@ public void StopServer()
public void SendMessageToAllClients(string message)
{
foreach (var clientContext in UiClients.Values)
- {
+ {
if (clientContext.Client != null && clientContext.Client.Context.WebSocket.IsAlive)
{
clientContext.Client.Context.WebSocket.Send(message);
@@ -915,9 +1057,12 @@ public void SendMessageToAllClients(string message)
///
public void SendMessageToClient(object clientId, string message)
{
- UiClientContext clientContext;
+ if (clientId == null)
+ {
+ return;
+ }
- if (UiClients.TryGetValue((string)clientId, out clientContext))
+ if (UiClients.TryGetValue((string)clientId, out UiClientContext clientContext))
{
if (clientContext.Client != null)
{
@@ -999,6 +1144,10 @@ public class JoinToken
public string RoomKey { get; set; }
public string Uuid { get; set; }
+
+ public string TouchpanelKey { get; set; } = "";
+
+ public string Token { get; set; } = null;
}
///
diff --git a/4-series/epi-essentials-mobile-control/WebSocketServer/WebSocketServerSecretProvider.cs b/4-series/epi-essentials-mobile-control/WebSocketServer/WebSocketServerSecretProvider.cs
index 8033881..7aa4099 100644
--- a/4-series/epi-essentials-mobile-control/WebSocketServer/WebSocketServerSecretProvider.cs
+++ b/4-series/epi-essentials-mobile-control/WebSocketServer/WebSocketServerSecretProvider.cs
@@ -1,19 +1,12 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
+using Newtonsoft.Json;
using PepperDash.Essentials.Core;
-using Newtonsoft.Json;
-
namespace PepperDash.Essentials
{
- class WebSocketServerSecretProvider : CrestronLocalSecretsProvider
+ internal class WebSocketServerSecretProvider : CrestronLocalSecretsProvider
{
public WebSocketServerSecretProvider(string key)
- :base(key)
+ : base(key)
{
Key = key;
}
diff --git a/4-series/epi-essentials-mobile-control/epi-essentials-mobile-control.csproj b/4-series/epi-essentials-mobile-control/epi-essentials-mobile-control.csproj
index 1e81e82..2bb7c9b 100644
--- a/4-series/epi-essentials-mobile-control/epi-essentials-mobile-control.csproj
+++ b/4-series/epi-essentials-mobile-control/epi-essentials-mobile-control.csproj
@@ -28,7 +28,7 @@
TRACE;SERIES4
-
+
@@ -43,7 +43,6 @@
-
diff --git a/4-series/mobile-control-messengers/ContentTypes.cs b/4-series/mobile-control-messengers/ContentTypes.cs
index 9a1d422..7945e71 100644
--- a/4-series/mobile-control-messengers/ContentTypes.cs
+++ b/4-series/mobile-control-messengers/ContentTypes.cs
@@ -1,21 +1,24 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Newtonsoft.Json;
+using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer
{
public class SourceSelectMessageContent
{
- public string SourceListItem { get; set; }
+ [JsonProperty("sourceListItemKey")]
+ public string SourceListItemKey { get; set; }
+ [JsonProperty("sourceListKey")]
public string SourceListKey { get; set; }
}
public class DirectRoute
{
+ [JsonProperty("sourceKey")]
public string SourceKey { get; set; }
+ [JsonProperty("destinationKey")]
public string DestinationKey { get; set; }
+ [JsonProperty("signalType")]
+ public eRoutingSignalType SignalType { get; set; }
}
///
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/CoreDisplayBaseMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/CoreDisplayBaseMessenger.cs
new file mode 100644
index 0000000..bf78271
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/CoreDisplayBaseMessenger.cs
@@ -0,0 +1,61 @@
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
+using System.Linq;
+using DisplayBase = PepperDash.Essentials.Core.DisplayBase;
+
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class CoreDisplayBaseMessenger: MessengerBase
+ {
+ private readonly DisplayBase display;
+
+ public CoreDisplayBaseMessenger(string key, string messagePath, DisplayBase device) : base(key, messagePath, device)
+ {
+ display = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ /* AddAction("/powerOn", (id, content) => display.PowerOn());
+ AddAction("/powerOff", (id, content) => display.PowerOff());
+ AddAction("/powerToggle", (id, content) => display.PowerToggle());*/
+
+ AddAction("/inputSelect", (id, content) =>
+ {
+ var s = content.ToObject>();
+
+ var inputPort = display.InputPorts.FirstOrDefault(i => i.Key == s.Value);
+
+ if (inputPort == null)
+ {
+ Debug.Console(1, "No input named {0} found for device {1}", s, display.Key);
+ return;
+ }
+
+ display.ExecuteSwitch(inputPort.Selector);
+ });
+
+ AddAction("/inputs", (id, content) =>
+ {
+ var inputsList = display.InputPorts.Select(p => p.Key).ToList();
+
+ var messageObject = new MobileControlMessage
+ {
+ Type = MessagePath + "/inputs",
+ Content = JToken.FromObject(new
+ {
+ inputKeys = inputsList,
+ })
+ };
+
+ AppServerController.SendMessageObject(messageObject);
+ });
+ }
+ }
+}
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/DisplayBaseExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/DisplayBaseExtensions.cs
deleted file mode 100644
index 571500e..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/DisplayBaseExtensions.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.Linq;
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class DisplayBaseExtensions
- {
- public static void LinkActions(this DisplayBase display, IMobileControl3 controller)
- {
- var prefix = String.Format(@"/device/{0}/", display.Key);
-
- controller.AddAction(prefix + "powerOn", new Action(display.PowerOn));
- controller.AddAction(prefix + "powerOff", new Action(display.PowerOff));
- controller.AddAction(prefix + "powerToggle", new Action(display.PowerToggle));
-
- controller.AddAction(prefix + "inputSelect", new Action((s) =>
- {
- var inputPort = display.InputPorts.FirstOrDefault(i => i.Key == s);
-
- if (inputPort == null)
- {
- Debug.Console(1, "No input named {0} found for device {1}", s, display.Key);
- return;
- }
-
- display.ExecuteSwitch(inputPort.Selector);
- }));
-
- controller.AddAction(prefix + "inputs", new Action(() =>
- {
- var inputsList = display.InputPorts.Select(p => p.Key).ToList();
-
- var messageObject = new
- {
- type = prefix + "inputs",
- content = new
- {
- inputKeys = inputsList,
- }
- };
-
- controller.SendMessageObject(messageObject);
- }));
- }
-
- public static void UnlinkActions(this DisplayBase display, IMobileControl3 controller)
- {
- var prefix = String.Format(@"/device/{0}/", display.Key);
-
- controller.RemoveAction(prefix + "powerOn");
- controller.RemoveAction(prefix + "powerOff");
- controller.RemoveAction(prefix + "powerToggle");
- controller.RemoveAction(prefix + "inputs");
- controller.RemoveAction(prefix + "inputSelect");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/DisplayBaseMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/DisplayBaseMessenger.cs
new file mode 100644
index 0000000..659c62e
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/DisplayBaseMessenger.cs
@@ -0,0 +1,61 @@
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
+using System.Linq;
+using DisplayBase = PepperDash.Essentials.Devices.Common.Displays.DisplayBase;
+
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class DisplayBaseMessenger: MessengerBase
+ {
+ private readonly DisplayBase display;
+
+ public DisplayBaseMessenger(string key, string messagePath, DisplayBase device) : base(key, messagePath, device)
+ {
+ display = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ /*AddAction("/powerOn", (id, content) => display.PowerOn());
+ AddAction("/powerOff", (id, content) => display.PowerOff());
+ AddAction("/powerToggle", (id, content) => display.PowerToggle());*/
+
+ AddAction("/inputSelect", (id, content) =>
+ {
+ var s = content.ToObject>();
+
+ var inputPort = display.InputPorts.FirstOrDefault(i => i.Key == s.Value);
+
+ if (inputPort == null)
+ {
+ Debug.Console(1, "No input named {0} found for device {1}", s, display.Key);
+ return;
+ }
+
+ display.ExecuteSwitch(inputPort.Selector);
+ });
+
+ AddAction("/inputs", (id, content) =>
+ {
+ var inputsList = display.InputPorts.Select(p => p.Key).ToList();
+
+ var messageObject = new MobileControlMessage
+ {
+ Type = MessagePath + "/inputs",
+ Content = JToken.FromObject(new
+ {
+ inputKeys = inputsList,
+ })
+ };
+
+ AppServerController.SendMessageObject(messageObject);
+ });
+ }
+ }
+}
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IChannelExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IChannelExtensions.cs
deleted file mode 100644
index 701230f..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IChannelExtensions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class ChannelExtensions
- {
- public static void LinkActions(this IChannel dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IChannelMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IChannelMessenger.cs
new file mode 100644
index 0000000..fa5b098
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IChannelMessenger.cs
@@ -0,0 +1,31 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+#if SERIES4
+#endif
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class IChannelMessenger:MessengerBase
+ {
+ private readonly IChannel channelDevice;
+
+ public IChannelMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ channelDevice = device as IChannel;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/chanUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => channelDevice?.ChannelUp(b)));
+
+ AddAction("/chanDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => channelDevice?.ChannelDown(b)));
+ AddAction("/lastChan", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => channelDevice?.LastChannel(b)));
+ AddAction("/guide", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => channelDevice?.Guide(b)));
+ AddAction("/info", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => channelDevice?.Info(b)));
+ AddAction("/exit", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => channelDevice?.Exit(b)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IColorExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IColorExtensions.cs
deleted file mode 100644
index 5210eb2..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IColorExtensions.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-
-
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class ColorExtensions
- {
- public static void LinkActions(this IColor dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).Key);
-
- controller.RemoveAction(prefix + "red");
- controller.RemoveAction(prefix + "green");
- controller.RemoveAction(prefix + "yellow");
- controller.RemoveAction(prefix + "blue");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IColorMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IColorMessenger.cs
new file mode 100644
index 0000000..04e64d9
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IColorMessenger.cs
@@ -0,0 +1,26 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class IColorMessenger:MessengerBase
+ {
+ private readonly IColor colorDevice;
+ public IColorMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ colorDevice = device as IColor;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/red", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => colorDevice?.Red(b)));
+ AddAction("/green", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => colorDevice?.Green(b)));
+ AddAction("/yellow", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => colorDevice?.Yellow(b)));
+ AddAction("/blue", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => colorDevice?.Blue(b)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDPadExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDPadExtensions.cs
deleted file mode 100644
index 87ff38e..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDPadExtensions.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class IdPadExtensions
- {
- public static void LinkActions(this IDPad dev, IMobileControl3 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, IMobileControl3 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");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDPadMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDPadMessenger.cs
new file mode 100644
index 0000000..251ff87
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDPadMessenger.cs
@@ -0,0 +1,31 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+#if SERIES4
+#endif
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class IDPadMessenger:MessengerBase
+ {
+ private readonly IDPad dpadDevice;
+ public IDPadMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ dpadDevice = device as IDPad;
+ }
+
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/up", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Up(b)));
+ AddAction("/down", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Down(b)));
+ AddAction("/left", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Left(b)));
+ AddAction("/right", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Right(b)));
+ AddAction("/select", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Select(b)));
+ AddAction("/menu", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Menu(b)));
+ AddAction("/exit", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dpadDevice?.Exit(b)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDvrExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDvrExtensions.cs
deleted file mode 100644
index e9941c5..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDvrExtensions.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class DvrExtensions
- {
- public static void LinkActions(this IDvr dev, IMobileControl3 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, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", (dev as IKeyed).Key);
-
- controller.RemoveAction(prefix + "dvrlist");
- controller.RemoveAction(prefix + "record");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDvrMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDvrMessenger.cs
new file mode 100644
index 0000000..399c113
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IDvrMessenger.cs
@@ -0,0 +1,26 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+#if SERIES4
+#endif
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class IDvrMessenger: MessengerBase
+ {
+ private readonly IDvr dvrDevice;
+ public IDvrMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ dvrDevice = device as IDvr;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/dvrlist", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dvrDevice?.DvrList(b)));
+ AddAction("/record", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => dvrDevice?.Record(b)));
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IHasPowerExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IHasPowerExtensions.cs
deleted file mode 100644
index e033c76..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IHasPowerExtensions.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class HasPowerExtensions
- {
- public static void LinkActions(this IHasPowerControl dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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 IHasPowerControl dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).Key);
-
- controller.RemoveAction(prefix + "powerOn");
- controller.RemoveAction(prefix + "powerOff");
- controller.RemoveAction(prefix + "powerToggle");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/IHasPowerMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IHasPowerMessenger.cs
new file mode 100644
index 0000000..33ce7ea
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/IHasPowerMessenger.cs
@@ -0,0 +1,25 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class IHasPowerMessenger:MessengerBase
+ {
+ private readonly IHasPowerControl powerDevice;
+ public IHasPowerMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ powerDevice = device as IHasPowerControl;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/powerOn", (id, content) => powerDevice?.PowerOn());
+ AddAction("/powerOff", (id, content) => powerDevice?.PowerOff());
+ AddAction("/powerToggle", (id, content) => powerDevice?.PowerToggle());
+ }
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/INumericExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/INumericExtensions.cs
deleted file mode 100644
index 7cc9ada..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/INumericExtensions.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class NumericExtensions
- {
- public static void LinkActions(this INumericKeypad dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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.Digit7));
- controller.AddAction(prefix + "num8", new PressAndHoldAction(dev.Digit8));
- controller.AddAction(prefix + "num9", new PressAndHoldAction(dev.Digit9));
- 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, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/INumericMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/INumericMessenger.cs
new file mode 100644
index 0000000..47cf829
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/INumericMessenger.cs
@@ -0,0 +1,36 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+#if SERIES4
+#endif
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class INumericKeypadMessenger:MessengerBase
+ {
+ private readonly INumericKeypad keypadDevice;
+ public INumericKeypadMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ keypadDevice = device as INumericKeypad;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/num0", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit0(b)));
+ AddAction("/num1", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit1(b)));
+ AddAction("/num2", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit2(b)));
+ AddAction("/num3", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit3(b)));
+ AddAction("/num4", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit4(b)));
+ AddAction("/num5", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit5(b)));
+ AddAction("/num6", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit6(b)));
+ AddAction("/num7", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit7(b)));
+ AddAction("/num8", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit8(b)));
+ AddAction("/num9", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.Digit9(b)));
+ AddAction("/numDash", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.KeypadAccessoryButton1(b)));
+ AddAction("/numEnter", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => keypadDevice?.KeypadAccessoryButton2(b)));
+ // Deal with the Accessory functions on the numpad later
+ }
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/ISetTopBoxControlsExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/ISetTopBoxControlsExtensions.cs
deleted file mode 100644
index 6064941..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/ISetTopBoxControlsExtensions.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class SetTopBoxControlsExtensions
- {
- public static void LinkActions(this ISetTopBoxControls dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", dev.Key);
-
- controller.AddAction(prefix + "dvrList", new PressAndHoldAction(dev.DvrList));
- controller.AddAction(prefix + "replay", new PressAndHoldAction(dev.Replay));
- }
-
- public static void UnlinkActions(this ISetTopBoxControls dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", dev.Key);
-
- controller.RemoveAction(prefix + "dvrList");
- controller.RemoveAction(prefix + "replay");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/ISetTopBoxControlsMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/ISetTopBoxControlsMessenger.cs
new file mode 100644
index 0000000..4927c33
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/ISetTopBoxControlsMessenger.cs
@@ -0,0 +1,25 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+#if SERIES4
+#endif
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class ISetTopBoxControlsMessenger:MessengerBase
+ {
+ private readonly ISetTopBoxControls stbDevice;
+ public ISetTopBoxControlsMessenger(string key, string messagePath, IKeyName device) : base(key, messagePath, device)
+ {
+ stbDevice = device as ISetTopBoxControls;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/dvrList", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => stbDevice?.DvrList(b)));
+ AddAction("/replay", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => stbDevice?.Replay(b)));
+ }
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/ITransportExtensions.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/ITransportExtensions.cs
deleted file mode 100644
index ebf563e..0000000
--- a/4-series/mobile-control-messengers/DeviceTypeExtenstions/ITransportExtensions.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using PepperDash.Essentials.Core;
-using PepperDash.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-#if SERIES4
-using PepperDash.Essentials.AppServer;
-#endif
-namespace PepperDash.Essentials.Room.MobileControl
-{
- public static class TransportExtensions
- {
- public static void LinkActions(this ITransport dev, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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, IMobileControl3 controller)
- {
- var prefix = string.Format(@"/device/{0}/", ((IKeyed) dev).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");
- }
- }
-}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/DeviceTypeExtenstions/ITransportMessenger.cs b/4-series/mobile-control-messengers/DeviceTypeExtenstions/ITransportMessenger.cs
new file mode 100644
index 0000000..c95f0eb
--- /dev/null
+++ b/4-series/mobile-control-messengers/DeviceTypeExtenstions/ITransportMessenger.cs
@@ -0,0 +1,32 @@
+using PepperDash.Core;
+using PepperDash.Essentials.AppServer.Messengers;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+#if SERIES4
+#endif
+namespace PepperDash.Essentials.Room.MobileControl
+{
+ public class ITransportMessenger:MessengerBase
+ {
+ private readonly ITransport transportDevice;
+ public ITransportMessenger(string key, string messagePath, Device device) : base(key, messagePath, device)
+ {
+ transportDevice = device as ITransport;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/play", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.Play(b)));
+ AddAction("/pause", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.Pause(b)));
+ AddAction("/stop", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.Stop(b)));
+ AddAction("/prevTrack", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.ChapPlus(b)));
+ AddAction("/nextTrack", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.ChapMinus(b)));
+ AddAction("/rewind", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.Rewind(b)));
+ AddAction("/ffwd", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.FFwd(b)));
+ AddAction("/record", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => transportDevice?.Record(b)));
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/4-series/mobile-control-messengers/Messengers/CoreTwoWayDisplayBaseMessenger.cs b/4-series/mobile-control-messengers/Messengers/CoreTwoWayDisplayBaseMessenger.cs
new file mode 100644
index 0000000..8bce8a4
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/CoreTwoWayDisplayBaseMessenger.cs
@@ -0,0 +1,91 @@
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class CoreTwoWayDisplayBaseMessenger : MessengerBase
+ {
+ private readonly TwoWayDisplayBase _display;
+
+ public CoreTwoWayDisplayBaseMessenger(string key, string messagePath, Device display)
+ : base(key, messagePath, display)
+ {
+ _display = display as TwoWayDisplayBase;
+ }
+
+ #region Overrides of MessengerBase
+
+ public void SendFullStatus()
+ {
+ var messageObj = new TwoWayDisplayBaseStateMessage
+ {
+ //PowerState = _display.PowerIsOnFeedback.BoolValue,
+ CurrentInput = _display.CurrentInputFeedback.StringValue
+ };
+
+ PostStatusMessage(messageObj);
+ }
+
+#if SERIES4
+ protected override void RegisterActions()
+#else
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
+#endif
+ {
+ base.RegisterActions();
+ if (_display == null)
+ {
+ Debug.Console(0, this, $"Unable to register TwoWayDisplayBase messenger {Key}");
+ return;
+ }
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
+
+ _display.PowerIsOnFeedback.OutputChange += PowerIsOnFeedbackOnOutputChange;
+ _display.CurrentInputFeedback.OutputChange += CurrentInputFeedbackOnOutputChange;
+ _display.IsCoolingDownFeedback.OutputChange += IsCoolingFeedbackOnOutputChange;
+ _display.IsWarmingUpFeedback.OutputChange += IsWarmingFeedbackOnOutputChange;
+ }
+
+ private void CurrentInputFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ currentInput = feedbackEventArgs.StringValue
+ }));
+ }
+
+
+ private void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ powerState = feedbackEventArgs.BoolValue
+ })
+ );
+ }
+
+ private void IsWarmingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ isWarming = feedbackEventArgs.BoolValue
+ })
+ );
+
+ }
+
+ private void IsCoolingFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ isCooling = feedbackEventArgs.BoolValue
+ })
+ );
+ }
+
+ #endregion
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/DeviceInfoMessenger.cs b/4-series/mobile-control-messengers/Messengers/DeviceInfoMessenger.cs
new file mode 100644
index 0000000..8a17ce0
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/DeviceInfoMessenger.cs
@@ -0,0 +1,47 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.DeviceInfo;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class DeviceInfoMessenger : MessengerBase
+ {
+ private readonly IDeviceInfoProvider _deviceInfoProvider;
+ public DeviceInfoMessenger(string key, string messagePath, IDeviceInfoProvider device) : base(key, messagePath, device as Device)
+ {
+ _deviceInfoProvider = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ _deviceInfoProvider.DeviceInfoChanged += (o, a) =>
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ deviceInfo = a.DeviceInfo
+ }));
+ };
+
+ AddAction("/fullStatus", (id, context) => PostStatusMessage(new DeviceInfoStateMessage
+ {
+ DeviceInfo = _deviceInfoProvider.DeviceInfo
+ }));
+
+ AddAction("/update", (id, context) => _deviceInfoProvider.UpdateDeviceInfo());
+ }
+ }
+
+ public class DeviceInfoStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("deviceInfo")]
+ public DeviceInfo DeviceInfo { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/ICommunicationMonitorMessenger.cs b/4-series/mobile-control-messengers/Messengers/ICommunicationMonitorMessenger.cs
new file mode 100644
index 0000000..7e4d03f
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/ICommunicationMonitorMessenger.cs
@@ -0,0 +1,79 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class ICommunicationMonitorMessenger : MessengerBase
+ {
+ private readonly ICommunicationMonitor _communicationMonitor;
+
+ public ICommunicationMonitorMessenger(string key, string messagePath, ICommunicationMonitor device) : base(key, messagePath, device as IKeyName)
+ {
+ _communicationMonitor = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) =>
+ {
+ PostStatusMessage(new CommunicationMonitorState
+ {
+ CommunicationMonitor = new CommunicationMonitorProps
+ {
+ IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
+ Status = _communicationMonitor.CommunicationMonitor.Status
+ }
+ });
+ });
+
+ _communicationMonitor.CommunicationMonitor.StatusChange += (sender, args) =>
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ commMonitor = new CommunicationMonitorProps
+ {
+ IsOnline = _communicationMonitor.CommunicationMonitor.IsOnline,
+ Status = _communicationMonitor.CommunicationMonitor.Status
+ }
+ }));
+ };
+ }
+ }
+
+ ///
+ /// Represents the state of the communication monitor
+ ///
+ public class CommunicationMonitorState : DeviceStateMessageBase
+ {
+ [JsonProperty("commMonitor", NullValueHandling = NullValueHandling.Ignore)]
+ public CommunicationMonitorProps CommunicationMonitor { get; set; }
+
+ }
+
+ public class CommunicationMonitorProps
+ { ///
+ /// For devices that implement ICommunicationMonitor, reports the online status of the device
+ ///
+ [JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IsOnline { get; set; }
+
+ ///
+ /// For devices that implement ICommunicationMonitor, reports the online status of the device
+ ///
+ [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public MonitorStatus Status { get; set; }
+
+ }
+
+}
diff --git a/4-series/mobile-control-messengers/Messengers/IHasCurrentSourceInfoMessenger.cs b/4-series/mobile-control-messengers/Messengers/IHasCurrentSourceInfoMessenger.cs
new file mode 100644
index 0000000..40a80a7
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/IHasCurrentSourceInfoMessenger.cs
@@ -0,0 +1,61 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class IHasCurrentSourceInfoMessenger : MessengerBase
+ {
+ private readonly IHasCurrentSourceInfoChange sourceDevice;
+ public IHasCurrentSourceInfoMessenger(string key, string messagePath, IHasCurrentSourceInfoChange device) : base(key, messagePath, device as IKeyName)
+ {
+ sourceDevice = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) =>
+ {
+ var message = new CurrentSourceStateMessage
+ {
+ CurrentSourceKey = sourceDevice.CurrentSourceInfoKey,
+ CurrentSource = sourceDevice.CurrentSourceInfo
+ };
+
+ PostStatusMessage(message);
+ });
+
+ sourceDevice.CurrentSourceChange += (sender, e) => {
+ switch (e)
+ {
+ case ChangeType.DidChange:
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ currentSourceKey = string.IsNullOrEmpty(sourceDevice.CurrentSourceInfoKey) ? string.Empty : sourceDevice.CurrentSourceInfoKey,
+ currentSource = sourceDevice.CurrentSourceInfo
+ }));
+ break;
+ }
+ }
+ };
+ }
+ }
+
+ public class CurrentSourceStateMessage: DeviceStateMessageBase
+ {
+ [JsonProperty("currentSourceKey", NullValueHandling = NullValueHandling.Ignore)]
+ public string CurrentSourceKey { get; set; }
+
+ [JsonProperty("currentSource")]
+ public SourceListItem CurrentSource { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/IHasPowerControlWithFeedbackMessenger.cs b/4-series/mobile-control-messengers/Messengers/IHasPowerControlWithFeedbackMessenger.cs
new file mode 100644
index 0000000..bf838e9
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/IHasPowerControlWithFeedbackMessenger.cs
@@ -0,0 +1,57 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Essentials.Core;
+using PepperDash.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class IHasPowerControlWithFeedbackMessenger: MessengerBase
+ {
+ private readonly IHasPowerControlWithFeedback _powerControl;
+
+ public IHasPowerControlWithFeedbackMessenger(string key, string messagePath, IHasPowerControlWithFeedback powerControl)
+ : base(key, messagePath, powerControl as Device)
+ {
+ _powerControl = powerControl;
+ }
+
+ public void SendFullStatus()
+ {
+ var messageObj = new PowerControlWithFeedbackStateMessage
+ {
+ PowerState = _powerControl.PowerIsOnFeedback.BoolValue
+ };
+
+ PostStatusMessage(messageObj);
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
+
+ _powerControl.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange; ;
+ }
+
+ private void PowerIsOnFeedback_OutputChange(object sender, FeedbackEventArgs args)
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ powerState = args.BoolValue
+ })
+ );
+ }
+ }
+
+ public class PowerControlWithFeedbackStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("powerState", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? PowerState { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/ILevelControlsMessenger.cs b/4-series/mobile-control-messengers/Messengers/ILevelControlsMessenger.cs
new file mode 100644
index 0000000..f8081ee
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/ILevelControlsMessenger.cs
@@ -0,0 +1,95 @@
+using Independentsoft.Exchange;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class ILevelControlsMessenger : MessengerBase
+ {
+ private ILevelControls levelControlsDevice;
+ public ILevelControlsMessenger(string key, string messagePath, ILevelControls device) : base(key, messagePath, device as Device)
+ {
+ levelControlsDevice = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, context) =>
+ {
+ var message = new LevelControlStateMessage
+ {
+ Levels = levelControlsDevice.LevelControlPoints.ToDictionary(kv => kv.Key, kv => new Volume { Level = kv.Value.VolumeLevelFeedback.IntValue, Muted = kv.Value.MuteFeedback.BoolValue })
+ };
+
+ PostStatusMessage(message);
+ });
+
+ foreach(var levelControl in levelControlsDevice.LevelControlPoints)
+ {
+ // reassigning here just in case of lambda closure issues
+ var key = levelControl.Key;
+ var control = levelControl.Value;
+
+ AddAction($"/{key}/level", (id, content) =>
+ {
+ var request = content.ToObject>();
+
+ control.SetVolume(request.Value);
+ });
+
+ AddAction($"/{key}/muteToggle", (id, content) =>
+ {
+ control.MuteToggle();
+ });
+
+ AddAction($"/{key}/muteOn", (id, content) => control.MuteOn());
+
+ AddAction($"/{key}/muteOff", (id, content) => control.MuteOff());
+
+ AddAction($"/{key}/volumeUp", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => control.VolumeUp(b)));
+
+ AddAction($"/{key}/volumeDown", (id, content) => PressAndHoldHandler.HandlePressAndHold(content, (b) => control.VolumeDown(b)));
+
+ control.VolumeLevelFeedback.OutputChange += (o, a) => PostStatusMessage(JToken.FromObject(new
+ {
+ levelControls = new Dictionary
+ {
+ {key, new Volume{Level = a.IntValue} }
+ }
+ }));
+
+ control.MuteFeedback.OutputChange += (o, a) => PostStatusMessage(JToken.FromObject(new
+ {
+ levelControls = new Dictionary
+ {
+ {key, new Volume{Muted = a.BoolValue} }
+ }
+ }));
+ }
+ }
+ }
+
+ public class LevelControlStateMessage:DeviceStateMessageBase
+ {
+ [JsonProperty("levelControls")]
+ public Dictionary Levels { get; set; }
+ }
+
+ public class LevelControlRequestMessage
+ {
+ [JsonProperty("key")]
+ public string Key { get; set; }
+
+ [JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
+ public ushort? Level { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/IMatrixRoutingMessenger.cs b/4-series/mobile-control-messengers/Messengers/IMatrixRoutingMessenger.cs
new file mode 100644
index 0000000..ba5ee55
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/IMatrixRoutingMessenger.cs
@@ -0,0 +1,168 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Routing;
+using System.Collections.Generic;
+using System.Linq;
+using Serilog.Events;
+using System;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ ///
+ /// Messenger for devices that implment IMatrixRouting
+ ///
+ public class IMatrixRoutingMessenger: MessengerBase
+ {
+ private readonly IMatrixRouting matrixDevice;
+ public IMatrixRoutingMessenger(string key, string messagePath, IMatrixRouting device) : base(key, messagePath, device as Device)
+ {
+ matrixDevice = device;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) =>
+ {
+ try
+ {
+ Debug.LogMessage(LogEventLevel.Verbose, "InputCount: {inputCount}, OutputCount: {outputCount}", this, matrixDevice.InputSlots.Count, matrixDevice.OutputSlots.Count);
+ var message = new MatrixStateMessage
+ {
+ Outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value)),
+ Inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value)),
+ };
+
+
+ PostStatusMessage(message);
+ }
+ catch (Exception e)
+ {
+ Debug.LogMessage(e, "Exception Getting full status: {@exception}", this, e);
+ }
+ });
+
+ AddAction("/route", (id, content) =>
+ {
+ var request = content.ToObject();
+
+ matrixDevice.Route(request.InputKey, request.OutputKey, request.RouteType);
+ });
+
+ foreach(var output in matrixDevice.OutputSlots)
+ {
+ var key = output.Key;
+ var outputSlot = output.Value;
+
+ outputSlot.OutputSlotChanged += (sender, args) =>
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ outputs = matrixDevice.OutputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingOutput(kvp.Value))
+ }));
+ };
+ }
+
+ foreach(var input in matrixDevice.InputSlots)
+ {
+ var key = input.Key;
+ var inputSlot = input.Value;
+
+ inputSlot.VideoSyncChanged += (sender, args) =>
+ {
+ PostStatusMessage(JToken.FromObject(new
+ {
+ inputs = matrixDevice.InputSlots.ToDictionary(kvp => kvp.Key, kvp => new RoutingInput(kvp.Value))
+ }));
+ };
+ }
+ }
+ }
+
+ public class MatrixStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("outputs")]
+ public Dictionary Outputs;
+
+ [JsonProperty("inputs")]
+ public Dictionary Inputs;
+ }
+
+ public class RoutingInput
+ {
+ private IRoutingInputSlot _input;
+
+ [JsonProperty("txDeviceKey", NullValueHandling = NullValueHandling.Ignore)]
+ public string TxDeviceKey => _input?.TxDeviceKey;
+
+ [JsonProperty("slotNumber", NullValueHandling = NullValueHandling.Ignore)]
+ public int? SlotNumber => _input?.SlotNumber;
+
+ [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
+ [JsonProperty("supportedSignalTypes", NullValueHandling = NullValueHandling.Ignore)]
+ public eRoutingSignalType? SupportedSignalTypes => _input?.SupportedSignalTypes;
+
+ [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
+ public string Name => _input?.Name;
+
+ [JsonProperty("isOnline", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IsOnline => _input?.IsOnline.BoolValue;
+
+ [JsonProperty("videoSyncDetected", NullValueHandling = NullValueHandling.Ignore)]
+
+ public bool? VideoSyncDetected => _input?.VideoSyncDetected;
+
+ [JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
+ public string Key => _input?.Key;
+
+ public RoutingInput(IRoutingInputSlot input)
+ {
+ _input = input;
+ }
+ }
+
+ public class RoutingOutput
+ {
+ private IRoutingOutputSlot _output;
+
+
+ public RoutingOutput(IRoutingOutputSlot output)
+ {
+ _output = output;
+ }
+
+ [JsonProperty("rxDeviceKey")]
+ public string RxDeviceKey => _output.RxDeviceKey;
+
+ [JsonProperty("currentRoutes")]
+ public Dictionary CurrentRoutes => _output.CurrentRoutes.ToDictionary(kvp => kvp.Key.ToString(), kvp => new RoutingInput(kvp.Value));
+
+ [JsonProperty("slotNumber")]
+ public int SlotNumber => _output.SlotNumber;
+
+ [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
+ [JsonProperty("supportedSignalTypes")]
+ public eRoutingSignalType SupportedSignalTypes => _output.SupportedSignalTypes;
+
+ [JsonProperty("name")]
+ public string Name => _output.Name;
+
+ [JsonProperty("key")]
+ public string Key => _output.Key;
+ }
+
+ public class MatrixRouteRequest
+ {
+ [JsonProperty("outputKey")]
+ public string OutputKey { get; set; }
+
+ [JsonProperty("inputKey")]
+ public string InputKey { get; set; }
+
+ [JsonProperty("routeType")]
+ public eRoutingSignalType RouteType { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/ISelectableItemsMessenger.cs b/4-series/mobile-control-messengers/Messengers/ISelectableItemsMessenger.cs
new file mode 100644
index 0000000..fe7ba9c
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/ISelectableItemsMessenger.cs
@@ -0,0 +1,63 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class ISelectableItemsMessenger : MessengerBase
+ {
+ private ISelectableItems itemDevice;
+
+ private readonly string _propName;
+ public ISelectableItemsMessenger(string key, string messagePath, ISelectableItems device, string propName) : base(key, messagePath, device as Device)
+ {
+ itemDevice = device;
+ _propName = propName;
+ }
+
+ protected override void RegisterActions()
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, context) =>
+ {
+ SendFullStatus();
+ });
+
+ itemDevice.ItemsUpdated += (sender, args) =>
+ {
+ SendFullStatus();
+ };
+
+ foreach (var input in itemDevice.Items)
+ {
+ var key = input.Key;
+ var localItem = input.Value;
+
+ AddAction($"/{localItem.Key}", (id, content) =>
+ {
+ localItem.Select();
+ });
+
+ localItem.ItemUpdated += (sender, args) =>
+ {
+ SendFullStatus();
+ };
+ }
+ }
+
+ private void SendFullStatus()
+ {
+ var stateObject = new JObject();
+ stateObject[_propName] = JToken.FromObject(itemDevice);
+ PostStatusMessage(stateObject);
+ }
+ }
+
+}
diff --git a/4-series/mobile-control-messengers/Messengers/IShutdownPromptTimerMessenger.cs b/4-series/mobile-control-messengers/Messengers/IShutdownPromptTimerMessenger.cs
new file mode 100644
index 0000000..b17ba7c
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/IShutdownPromptTimerMessenger.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class IShutdownPromptTimerMessenger : MessengerBase
+ {
+ private readonly IShutdownPromptTimer _room;
+
+ public IShutdownPromptTimerMessenger(string key, string messagePath, IShutdownPromptTimer room)
+ : base(key, messagePath, room as Device)
+ {
+ _room = room;
+ }
+
+ protected override void RegisterActions()
+ {
+ AddAction("/status", (id, content) =>
+ {
+ SendFullStatus();
+ });
+
+ AddAction("/setShutdownPromptSeconds", (id, content) =>
+ {
+ var response = content.ToObject();
+
+ _room.SetShutdownPromptSeconds(response);
+
+ SendFullStatus();
+ });
+
+ AddAction("/shutdownStart", (id, content) => _room.StartShutdown(eShutdownType.Manual));
+
+ AddAction("/shutdownEnd", (id, content) => _room.ShutdownPromptTimer.Finish());
+
+ AddAction("/shutdownCancel", (id, content) => _room.ShutdownPromptTimer.Cancel());
+
+
+ _room.ShutdownPromptTimer.HasStarted += (sender, args) =>
+ {
+ PostEventMessage("timerStarted");
+ };
+
+ _room.ShutdownPromptTimer.HasFinished += (sender, args) =>
+ {
+
+ PostEventMessage("timerFinished");
+ };
+
+ _room.ShutdownPromptTimer.WasCancelled += (sender, args) =>
+ {
+ PostEventMessage("timerCancelled");
+ };
+
+ _room.ShutdownPromptTimer.SecondsRemainingFeedback.OutputChange += (sender, args) =>
+ {
+ var status = new
+ {
+ secondsRemaining = _room.ShutdownPromptTimer.SecondsRemainingFeedback.IntValue,
+ percentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
+ };
+
+ PostStatusMessage(JToken.FromObject(status));
+ };
+ }
+
+ private void SendFullStatus()
+ {
+ var status = new IShutdownPromptTimerStateMessage
+ {
+ ShutdownPromptSeconds = _room.ShutdownPromptTimer.SecondsToCount,
+ SecondsRemaining = _room.ShutdownPromptTimer.SecondsRemainingFeedback.IntValue,
+ PercentageRemaining = _room.ShutdownPromptTimer.PercentFeedback.UShortValue
+ };
+
+ PostStatusMessage(status);
+ }
+ }
+
+
+ public class IShutdownPromptTimerStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("secondsRemaining")]
+ public int SecondsRemaining { get; set; }
+
+ [JsonProperty("percentageRemaining")]
+ public int PercentageRemaining { get; set; }
+
+ [JsonProperty("shutdownPromptSeconds")]
+ public int ShutdownPromptSeconds { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/ISwitchedOutputMessenger.cs b/4-series/mobile-control-messengers/Messengers/ISwitchedOutputMessenger.cs
new file mode 100644
index 0000000..6d3bceb
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/ISwitchedOutputMessenger.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using PepperDash.Essentials.Core.CrestronIO;
+using PepperDash.Essentials.Core.Shades;
+using Newtonsoft.Json;
+using PepperDash.Core;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class ISwitchedOutputMessenger : MessengerBase
+ {
+
+ private readonly ISwitchedOutput device;
+
+ public ISwitchedOutputMessenger(string key, ISwitchedOutput device, string messagePath)
+ : base(key, messagePath, device as Device)
+ {
+ this.device = device;
+ }
+
+#if SERIES4
+ protected override void RegisterActions()
+#else
+ protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController)
+#endif
+ {
+ base.RegisterActions();
+
+ AddAction("/fullStatus", (id, content) => SendFullStatus());
+
+ AddAction("/on", (id, content) =>
+ {
+
+ device.On();
+
+ });
+
+ AddAction("/off", (id, content) =>
+ {
+
+ device.Off();
+
+ });
+
+ device.OutputIsOnFeedback.OutputChange += new EventHandler((o, a) => SendFullStatus());
+ }
+
+ private void SendFullStatus()
+ {
+ var state = new ISwitchedOutputStateMessage
+ {
+ IsOn = device.OutputIsOnFeedback.BoolValue
+ };
+
+ PostStatusMessage(state);
+ }
+ }
+
+ public class ISwitchedOutputStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("isOn")]
+ public bool IsOn { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Messengers/ITechPasswordMessenger.cs b/4-series/mobile-control-messengers/Messengers/ITechPasswordMessenger.cs
new file mode 100644
index 0000000..46e2a5a
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/ITechPasswordMessenger.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Independentsoft.Json.Parser;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public class ITechPasswordMessenger : MessengerBase
+ {
+ private readonly ITechPassword _room;
+
+ public ITechPasswordMessenger(string key, string messagePath, ITechPassword room)
+ : base(key, messagePath, room as Device)
+ {
+ _room = room;
+ }
+
+ protected override void RegisterActions()
+ {
+
+ AddAction("/status", (id, content) =>
+ {
+ SendFullStatus();
+ });
+
+ AddAction("/validateTechPassword", (id, content) =>
+ {
+ var password = content.Value("password");
+
+ _room.ValidateTechPassword(password);
+ });
+
+ AddAction("/setTechPassword", (id, content) =>
+ {
+ var response = content.ToObject();
+
+ _room.SetTechPassword(response.OldPassword, response.NewPassword);
+ });
+
+ _room.TechPasswordChanged += (sender, args) =>
+ {
+ PostEventMessage("passwordChangedSuccessfully");
+ };
+
+ _room.TechPasswordValidateResult += (sender, args) =>
+ {
+ var evt = new ITechPasswordEventMessage
+ {
+ IsValid = args.IsValid
+ };
+
+ PostEventMessage(evt, "passwordValidationResult");
+ };
+ }
+
+ private void SendFullStatus()
+ {
+ var status = new ITechPasswordStateMessage
+ {
+ TechPasswordLength = _room.TechPasswordLength
+ };
+
+ PostStatusMessage(status);
+ }
+
+ }
+
+ public class ITechPasswordStateMessage : DeviceStateMessageBase
+ {
+ [JsonProperty("techPasswordLength", NullValueHandling = NullValueHandling.Ignore)]
+ public int? TechPasswordLength { get; set; }
+ }
+
+ public class ITechPasswordEventMessage : DeviceEventMessageBase
+ {
+ [JsonProperty("isValid", NullValueHandling = NullValueHandling.Ignore)]
+ public bool? IsValid { get; set; }
+ }
+
+ class SetTechPasswordContent
+ {
+ [JsonProperty("oldPassword")]
+ public string OldPassword { get; set; }
+
+ [JsonProperty("newPassword")]
+ public string NewPassword { get; set; }
+ }
+
+}
diff --git a/4-series/mobile-control-messengers/Messengers/PressAndHoldHandler.cs b/4-series/mobile-control-messengers/Messengers/PressAndHoldHandler.cs
new file mode 100644
index 0000000..44c51ab
--- /dev/null
+++ b/4-series/mobile-control-messengers/Messengers/PressAndHoldHandler.cs
@@ -0,0 +1,96 @@
+using Crestron.SimplSharp;
+using Newtonsoft.Json.Linq;
+using PepperDash.Core;
+using System;
+using System.Collections.Generic;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+ public static class PressAndHoldHandler
+ {
+ private const long ButtonHeartbeatInterval = 1000;
+
+ private static readonly Dictionary _pushedActions = new Dictionary();
+
+ private static readonly Dictionary>> _pushedActionHandlers;
+
+ static PressAndHoldHandler()
+ {
+ _pushedActionHandlers = new Dictionary>>
+ {
+ {"pressed", AddTimer },
+ {"held", ResetTimer },
+ {"released", StopTimer }
+ };
+ }
+
+ private static void AddTimer(string type, Action action)
+ {
+
+ if (_pushedActions.TryGetValue(type, out CTimer cancelTimer))
+ {
+ return;
+ }
+
+ cancelTimer = new CTimer(o =>
+ {
+ action(false);
+
+ _pushedActions.Remove(type);
+ }, ButtonHeartbeatInterval);
+
+ _pushedActions.Add(type, cancelTimer);
+ }
+
+ private static void ResetTimer(string type, Action action)
+ {
+
+ if (!_pushedActions.TryGetValue(type, out CTimer cancelTimer)) { return; }
+
+ cancelTimer.Reset(ButtonHeartbeatInterval);
+ }
+
+ private static void StopTimer(string type, Action action)
+ {
+
+ if (!_pushedActions.TryGetValue(type, out CTimer cancelTimer)) { return; }
+
+ action(false);
+ cancelTimer.Stop();
+ _pushedActions.Remove(type);
+ }
+
+ public static Action> GetPressAndHoldHandler(string value)
+ {
+
+ if (!_pushedActionHandlers.TryGetValue(value, out Action> handler))
+ {
+ Debug.Console(0, "Unable to get Press & Hold handler for {0}", value);
+ return null;
+ }
+
+ return handler;
+ }
+
+ public static void HandlePressAndHold(JToken content, Action action)
+ {
+ var msg = content.ToObject>();
+
+ Debug.Console(2, "HandlePressAndHold msg: {0}", msg.Value);
+
+
+ var timerHandler = GetPressAndHoldHandler(msg.Value);
+ if (timerHandler == null)
+ {
+ return;
+ }
+
+ timerHandler(msg.Value, action);
+
+ if (msg.Value.Equals("pressed", StringComparison.InvariantCultureIgnoreCase))
+ action(true);
+ else if (msg.Value.Equals("released", StringComparison.InvariantCultureIgnoreCase))
+ action(false);
+ }
+ }
+}
diff --git a/4-series/mobile-control-messengers/MobileControlMessage.cs b/4-series/mobile-control-messengers/MobileControlMessage.cs
new file mode 100644
index 0000000..5e284df
--- /dev/null
+++ b/4-series/mobile-control-messengers/MobileControlMessage.cs
@@ -0,0 +1,23 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using PepperDash.Essentials.Core.DeviceTypeInterfaces;
+
+namespace PepperDash.Essentials.AppServer.Messengers
+{
+
+#if SERIES4
+ public class MobileControlMessage : IMobileControlMessage
+#else
+ public class MobileControlMessage
+#endif
+ {
+ [JsonProperty("type")]
+ public string Type { get; set; }
+
+ [JsonProperty("clientId")]
+ public string ClientId { get; set; }
+
+ [JsonProperty("content")]
+ public JToken Content { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/MobileControlSimpleContent.cs b/4-series/mobile-control-messengers/MobileControlSimpleContent.cs
new file mode 100644
index 0000000..1d80475
--- /dev/null
+++ b/4-series/mobile-control-messengers/MobileControlSimpleContent.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials.AppServer
+{
+ public class MobileControlSimpleContent
+ {
+ [JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
+ public T Value { get; set; }
+ }
+}
diff --git a/4-series/mobile-control-messengers/Properties/AssemblyInfo.cs b/4-series/mobile-control-messengers/Properties/AssemblyInfo.cs
index 7afd4db..2d559a0 100644
--- a/4-series/mobile-control-messengers/Properties/AssemblyInfo.cs
+++ b/4-series/mobile-control-messengers/Properties/AssemblyInfo.cs
@@ -1,6 +1,4 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices;
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
diff --git a/4-series/mobile-control-messengers/mobile-control-messengers.csproj b/4-series/mobile-control-messengers/mobile-control-messengers.csproj
index 22e3dcf..986b110 100644
--- a/4-series/mobile-control-messengers/mobile-control-messengers.csproj
+++ b/4-series/mobile-control-messengers/mobile-control-messengers.csproj
@@ -28,7 +28,6 @@
-
@@ -36,7 +35,6 @@
-
@@ -48,7 +46,7 @@
-
+
@@ -60,10 +58,9 @@
-
-
+
\ No newline at end of file