diff --git a/.github/scripts/GenerateVersionNumber.ps1 b/.github/scripts/GenerateVersionNumber.ps1 new file mode 100644 index 00000000..467ce883 --- /dev/null +++ b/.github/scripts/GenerateVersionNumber.ps1 @@ -0,0 +1,45 @@ +$latestVersions = $(git tag --merged origin/master) +$latestVersion = [version]"0.0.0" +Foreach ($version in $latestVersions) { + Write-Host $version + try { + if (([version]$version) -ge $latestVersion) { + $latestVersion = $version + Write-Host "Setting latest version to: $latestVersion" + } + } + catch { + Write-Host "Unable to convert $($version). Skipping" + continue; + } +} + +$newVersion = [version]$latestVersion +$phase = "" +$newVersionString = "" +switch -regex ($Env:GITHUB_REF) { + '^refs\/heads\/master*.' { + $newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build + } + '^refs\/heads\/feature\/*.' { + $phase = 'alpha' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } + '^refs\/heads\/release\/*.' { + $splitRef = $Env:GITHUB_REF -split "/" + $version = [version]($splitRef[-1] -replace "v", "") + $phase = 'rc' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $version.Major, $version.Minor, $version.Build, $phase, $Env:GITHUB_RUN_NUMBER + } + '^refs\/heads\/development*.' { + $phase = 'beta' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } + '^refs\/heads\/hotfix\/*.' { + $phase = 'hotfix' + $newVersionString = "{0}.{1}.{2}-{3}-{4}" -f $newVersion.Major, $newVersion.Minor, ($newVersion.Build + 1), $phase, $Env:GITHUB_RUN_NUMBER + } +} + + +Write-Output $newVersionString diff --git a/.github/scripts/UpdateAssemblyVersion.ps1 b/.github/scripts/UpdateAssemblyVersion.ps1 new file mode 100644 index 00000000..e52b31e6 --- /dev/null +++ b/.github/scripts/UpdateAssemblyVersion.ps1 @@ -0,0 +1,40 @@ +function Update-SourceVersion { + Param ([string]$Version) + #$fullVersion = $Version + $baseVersion = [regex]::Match($Version, "(\d+.\d+.\d+).*").captures.groups[1].value + $NewAssemblyVersion = ‘AssemblyVersion("‘ + $baseVersion + ‘.*")’ + Write-Output "AssemblyVersion = $NewAssemblyVersion" + $NewAssemblyInformationalVersion = ‘AssemblyInformationalVersion("‘ + $Version + ‘")’ + Write-Output "AssemblyInformationalVersion = $NewAssemblyInformationalVersion" + + foreach ($o in $input) { + Write-output $o.FullName + $TmpFile = $o.FullName + “.tmp” + get-content $o.FullName | + ForEach-Object { + $_ -replace ‘AssemblyVersion\(".*"\)’, $NewAssemblyVersion } | + ForEach-Object { + $_ -replace ‘AssemblyInformationalVersion\(".*"\)’, $NewAssemblyInformationalVersion + } > $TmpFile + move-item $TmpFile $o.FullName -force + } +} + +function Update-AllAssemblyInfoFiles ( $version ) { + foreach ($file in “AssemblyInfo.cs”, “AssemblyInfo.vb” ) { + get-childitem -Path $Env:GITHUB_WORKSPACE -recurse | Where-Object { $_.Name -eq $file } | Update-SourceVersion $version ; + } +} + +# validate arguments +$r = [System.Text.RegularExpressions.Regex]::Match($args[0], "\d+\.\d+\.\d+.*"); +if ($r.Success) { + Write-Output "Updating Assembly Version to $args ..."; + Update-AllAssemblyInfoFiles $args[0]; +} +else { + Write-Output ” “; + Write-Output “Error: Input version does not match x.y.z format!” + Write-Output ” “; + Write-Output "Unable to apply version to AssemblyInfo.cs files"; +} diff --git a/.github/scripts/ZipBuildOutput.ps1 b/.github/scripts/ZipBuildOutput.ps1 new file mode 100644 index 00000000..ac87aeb7 --- /dev/null +++ b/.github/scripts/ZipBuildOutput.ps1 @@ -0,0 +1,43 @@ +# Uncomment these for local testing +# $Env:GITHUB_WORKSPACE = "C:\Working Directories\PD\essentials" +# $Env:SOLUTION_FILE = "PepperDashEssentials" +# $Env:VERSION = "0.0.0-buildType-test" + +# Sets the root directory for the operation +$destination = "$($Env:GITHUB_HOME)\output" +New-Item -ItemType Directory -Force -Path ($destination) +Get-ChildItem ($destination) +$exclusions = @(git submodule foreach --quiet 'echo $name') +# 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" | 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\*.cpz | Rename-Item -NewName { "$($_.BaseName)-$($Env:VERSION)$($_.Extension)" } +Compress-Archive -Path $destination -DestinationPath "$($Env:GITHUB_WORKSPACE)\$($Env:SOLUTION_FILE)-$($Env:VERSION).zip" -Force +Write-Host "Output Contents post Zip" +Get-ChildItem -Path $destination \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..ffb235e6 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,252 @@ +name: Branch Build Using Docker + +on: + push: + branches: + - feature/* + - hotfix/* + - release/* + - development + +env: + # solution path doesn't need slashes unless there it is multiple folders deep + # solution name does not include extension. .sln is assumed + SOLUTION_PATH: PepperDashEssentials + SOLUTION_FILE: PepperDashEssentials + # Do not edit this, we're just creating it here + VERSION: 0.0.0-buildtype-buildnumber + # Defaults to debug for build type + BUILD_TYPE: Debug + # Defaults to master as the release branch. Change as necessary + RELEASE_BRANCH: master +jobs: + Build_Project: + runs-on: windows-latest + steps: + # First we checkout the source repo + - name: Checkout repo + uses: actions/checkout@v2 + with: + fetch-depth: 0 + # And any submodules + - name: Checkout submodules + shell: bash + run: | + git config --global url."https://github.com/".insteadOf "git@github.com:" + auth_header="$(git config --local --get http.https://github.com/.extraheader)" + git submodule sync --recursive + git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 + # Fetch all tags + - name: Fetch tags + run: git fetch --tags + # Generate the appropriate version number + - name: Set Version Number + shell: powershell + run: | + $version = ./.github/scripts/GenerateVersionNumber.ps1 + Write-Output "::set-env name=VERSION::$version" + # Use the version number to set the version of the assemblies + - name: Update AssemblyInfo.cs + shell: powershell + run: | + Write-Output ${{ env.VERSION }} + ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }} + # Build the solutions in the docker image + - name: Build Solution + shell: powershell + run: | + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + # Zip up the output files as needed + - name: Zip Build Output + shell: powershell + run: ./.github/scripts/ZipBuildOutput.ps1 + # Write the version to a file to be consumed by the push jobs + - name: Write Version + run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt" + # Upload the build output as an artifact + - name: Upload Build Output + uses: actions/upload-artifact@v1 + with: + name: Build + path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + # Upload the Version file as an artifact + - name: Upload version.txt + uses: actions/upload-artifact@v1 + with: + name: Version + path: ${{env.GITHUB_HOME}}\output\version.txt + # Create the release on the source repo + - name: Create Release + id: create_release + # using contributor's version to allow for pointing at the right commit + uses: fleskesvor/create-release@feature/support-target-commitish + with: + tag_name: ${{ env.VERSION }} + release_name: ${{ env.VERSION }} + prerelease: ${{contains('debug', env.BUILD_TYPE)}} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Upload the build package to the release + - name: Upload Release Package + id: upload_release + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + asset_content_type: application/zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # This step always runs and pushes the build to the internal build rep + Internal_Push_Output: + needs: Build_Project + runs-on: windows-latest + steps: + # Checkout the repo + - name: Checkout Builds Repo + uses: actions/checkout@v2 + with: + token: ${{ secrets.BUILDS_TOKEN }} + repository: PepperDash-Engineering/essentials-builds + ref: ${{ Env.GITHUB_REF }} + # Download the version artifact from the build job + - name: Download Build Version Info + uses: actions/download-artifact@v1 + with: + name: Version + - name: Check Directory + run: Get-ChildItem "./" + # Set the version number environment variable from the file we just downloaded + - name: Set Version Number + shell: powershell + run: | + Get-ChildItem "./Version" + $version = Get-Content -Path ./Version/version.txt + Write-Host "Version: $version" + Write-Output "::set-env name=VERSION::$version" + Remove-Item -Path ./Version/version.txt + Remove-Item -Path ./Version + # Checkout/Create the branch + - name: Create new branch + run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/") + # Download the build output into the repo + - name: Download Build output + uses: actions/download-artifact@v1 + with: + name: Build + path: ./ + - name: Check directory + run: Get-ChildItem ./ + # Unzip the build package file + - name: Unzip Build file + run: | + Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ + Remove-Item -Path .\*.zip + - name: Check directory again + run: Get-ChildItem ./ + # Copy Contents of output folder to root directory + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse + # Commits the build output to the branch and tags it with the version + - name: Commit build output and tag the commit + shell: powershell + run: | + git config user.email "actions@pepperdash.com" + git config user.name "GitHub Actions" + git add . + $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" + Write-Host "Commit: $commit" + git commit -m $commit + git tag $($Env:VERSION) + # Push the commit + - name: Push to Builds Repo + shell: powershell + run: | + $branch = $($Env:GITHUB_REF) -replace "refs/heads/" + Write-Host "Branch: $branch" + git push -u origin $($branch) --force + # Push the tags + - name: Push tags + run: git push --tags origin + - name: Check Directory + run: Get-ChildItem ./ + # This step only runs if the branch is master or release/ runs and pushes the build to the public build repo + Public_Push_Output: + needs: Build_Project + runs-on: windows-latest + if: contains(github.ref, 'master') || contains(github.ref, 'release') + steps: + # Checkout the repo + - name: Checkout Builds Repo + uses: actions/checkout@v2 + with: + token: ${{ secrets.BUILDS_TOKEN }} + repository: PepperDash/Essentials-Builds + ref: ${{ Env.GITHUB_REF }} + # Download the version artifact from the build job + - name: Download Build Version Info + uses: actions/download-artifact@v1 + with: + name: Version + - name: Check Directory + run: Get-ChildItem "./" + # Set the version number environment variable from the file we just downloaded + - name: Set Version Number + shell: powershell + run: | + Get-ChildItem "./Version" + $version = Get-Content -Path ./Version/version.txt + Write-Host "Version: $version" + Write-Output "::set-env name=VERSION::$version" + Remove-Item -Path ./Version/version.txt + Remove-Item -Path ./Version + # Checkout/Create the branch + - name: Create new branch + run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/") + # Download the build output into the repo + - name: Download Build output + uses: actions/download-artifact@v1 + with: + name: Build + path: ./ + - name: Check directory + run: Get-ChildItem ./ + # Unzip the build package file + - name: Unzip Build file + run: | + Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ + Remove-Item -Path .\*.zip + - name: Check directory again + run: Get-ChildItem ./ + # Copy Contents of output folder to root directory + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse + # Commits the build output to the branch and tags it with the version + - name: Commit build output and tag the commit + shell: powershell + run: | + git config user.email "actions@pepperdash.com" + git config user.name "GitHub Actions" + git add . + $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" + Write-Host "Commit: $commit" + git commit -m $commit + git tag $($Env:VERSION) + # Push the commit + - name: Push to Builds Repo + shell: powershell + run: | + $branch = $($Env:GITHUB_REF) -replace "refs/heads/" + Write-Host "Branch: $branch" + git push -u origin $($branch) --force + # Push the tags + - name: Push tags + run: git push --tags origin + - name: Check Directory + run: Get-ChildItem ./ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 5fb11cc8..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Build Non-Release Branch - -on: - push: - branches: - - feature/* - - bugfix/* - - hotfix/* - -jobs: - build: - name: Build - runs-on: self-hosted - steps: - - run: Invoke-WebRequest -URI "http://localhost:8080/job/Essentials%20Builds/build?token=$($Env:projectToken)" -Headers @{Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("ndorin:$($Env:token)")))"} -Method POST -UseBasicParsing - env: - token: ${{ secrets.TOKEN }} - projectToken: ${{ secrets.PROJECTTOKEN}} diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml new file mode 100644 index 00000000..b0f3fa6e --- /dev/null +++ b/.github/workflows/master.yml @@ -0,0 +1,227 @@ +name: Master Build using Docker + +on: + release: + types: + - created + branches: + - master +env: + # solution path doesn't need slashes unless there it is multiple folders deep + # solution name does not include extension. .sln is assumed + SOLUTION_PATH: PepperDashEssentials + SOLUTION_FILE: PepperDashEssentials + # Do not edit this, we're just creating it here + VERSION: 0.0.0-buildtype-buildnumber + # Defaults to debug for build type + BUILD_TYPE: Release + # Defaults to master as the release branch. Change as necessary + RELEASE_BRANCH: master +jobs: + Build_Project: + runs-on: windows-latest + steps: + # First we checkout the source repo + - name: Checkout repo + uses: actions/checkout@v2 + # And any submodules + - name: Checkout submodules + shell: bash + run: | + git config --global url."https://github.com/".insteadOf "git@github.com:" + auth_header="$(git config --local --get http.https://github.com/.extraheader)" + git submodule sync --recursive + git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 + # Fetch all tags + - name: Fetch tags + run: git fetch --tags + # Generate the appropriate version number + - name: Set Version Number + shell: powershell + env: + TAG_NAME: ${{ github.event.release.tag_name }} + run: Write-Output "::set-env name=VERSION::$($Env:TAG_NAME)" + # Use the version number to set the version of the assemblies + - name: Update AssemblyInfo.cs + shell: powershell + run: | + Write-Output ${{ env.VERSION }} + ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }} + # Build the solutions in the docker image + - name: Build Solution + shell: powershell + run: | + Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)" + # Zip up the output files as needed + - name: Zip Build Output + shell: powershell + run: ./.github/scripts/ZipBuildOutput.ps1 + - name: Upload Build Output + uses: actions/upload-artifact@v1 + with: + name: Build + path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip + # 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 }} + # This step always runs and pushes the build to the internal build rep + Internal_Push_Output: + needs: Build_Project + runs-on: windows-latest + steps: + # Checkout the repo + - name: Checkout Builds Repo + uses: actions/checkout@v2 + with: + token: ${{ secrets.BUILDS_TOKEN }} + repository: PepperDash-Engineering/essentials-builds + ref: ${{ Env.GITHUB_REF }} + # Download the version artifact from the build job + - name: Download Build Version Info + uses: actions/download-artifact@v1 + with: + name: Version + - name: Check Directory + run: Get-ChildItem "./" + # Set the version number environment variable from the file we just downloaded + - name: Set Version Number + shell: powershell + run: | + Get-ChildItem "./Version" + $version = Get-Content -Path ./Version/version.txt + Write-Host "Version: $version" + Write-Output "::set-env name=VERSION::$version" + Remove-Item -Path ./Version/version.txt + Remove-Item -Path ./Version + # Checkout/Create the branch + - name: Create new branch + run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/") + # Download the build output into the repo + - name: Download Build output + uses: actions/download-artifact@v1 + with: + name: Build + path: ./ + - name: Check directory + run: Get-ChildItem ./ + # Unzip the build package file + - name: Unzip Build file + run: | + Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ + Remove-Item -Path .\*.zip + - name: Check directory again + run: Get-ChildItem ./ + # Copy Contents of output folder to root directory + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse + # Commits the build output to the branch and tags it with the version + - name: Commit build output and tag the commit + shell: powershell + run: | + git config user.email "actions@pepperdash.com" + git config user.name "GitHub Actions" + git add . + $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" + Write-Host "Commit: $commit" + git commit -m $commit + git tag $($Env:VERSION) + # Push the commit + - name: Push to Builds Repo + shell: powershell + run: | + $branch = $($Env:GITHUB_REF) -replace "refs/heads/" + Write-Host "Branch: $branch" + git push -u origin $($branch) --force + # Push the tags + - name: Push tags + run: git push --tags origin + - name: Check Directory + run: Get-ChildItem ./ + # This step only runs if the branch is master or release/ runs and pushes the build to the public build repo + Public_Push_Output: + needs: Build_Project + runs-on: windows-latest + if: contains(github.ref, 'master') || contains(github.ref, 'release') + steps: + # Checkout the repo + - name: Checkout Builds Repo + uses: actions/checkout@v2 + with: + token: ${{ secrets.BUILDS_TOKEN }} + repository: PepperDash/Essentials-Builds + ref: ${{ Env.GITHUB_REF }} + # Download the version artifact from the build job + - name: Download Build Version Info + uses: actions/download-artifact@v1 + with: + name: Version + - name: Check Directory + run: Get-ChildItem "./" + # Set the version number environment variable from the file we just downloaded + - name: Set Version Number + shell: powershell + run: | + Get-ChildItem "./Version" + $version = Get-Content -Path ./Version/version.txt + Write-Host "Version: $version" + Write-Output "::set-env name=VERSION::$version" + Remove-Item -Path ./Version/version.txt + Remove-Item -Path ./Version + # Checkout/Create the branch + - name: Create new branch + run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/") + # Download the build output into the repo + - name: Download Build output + uses: actions/download-artifact@v1 + with: + name: Build + path: ./ + - name: Check directory + run: Get-ChildItem ./ + # Unzip the build package file + - name: Unzip Build file + run: | + Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\ + Remove-Item -Path .\*.zip + - name: Check directory again + run: Get-ChildItem ./ + # Copy Contents of output folder to root directory + - name: Copy Files to root & delete output directory + run: | + Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz") + Get-ChildItem -Path .\output\* | Copy-Item -Destination .\ + Remove-Item -Path .\output -Recurse + # Commits the build output to the branch and tags it with the version + - name: Commit build output and tag the commit + shell: powershell + run: | + git config user.email "actions@pepperdash.com" + git config user.name "GitHub Actions" + git add . + $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)" + Write-Host "Commit: $commit" + git commit -m $commit + git tag $($Env:VERSION) + # Push the commit + - name: Push to Builds Repo + shell: powershell + run: | + $branch = $($Env:GITHUB_REF) -replace "refs/heads/" + Write-Host "Branch: $branch" + git push -u origin $($branch) --force + # Push the tags + - name: Push tags + run: git push --tags origin + - name: Check Directory + run: Get-ChildItem ./ diff --git a/.gitignore b/.gitignore index 4d389dc6..5ba628b2 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ _ReSharper*/ SIMPLSharpLogs/ *.projectinfo essentials-framework/EssentialDMTestConfig/ +output/ + +PepperDashEssentials-0.0.0-buildType-test.zip diff --git a/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs b/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs index 080fbd78..9e41722e 100644 --- a/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs +++ b/PepperDashEssentials/AppServer/Messengers/SystemMonitorMessenger.cs @@ -1,11 +1,5 @@ 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.Monitoring; @@ -23,11 +17,11 @@ namespace PepperDash.Essentials.AppServer.Messengers SysMon = sysMon; - SysMon.SystemMonitorPropertiesChanged += new EventHandler(SysMon_SystemMonitorPropertiesChanged); + SysMon.SystemMonitorPropertiesChanged += SysMon_SystemMonitorPropertiesChanged; foreach (var p in SysMon.ProgramStatusFeedbackCollection) { - p.Value.ProgramInfoChanged += new EventHandler(ProgramInfoChanged); + p.Value.ProgramInfoChanged += ProgramInfoChanged; } CrestronConsole.AddNewConsoleCommand(s => SendFullStatusMessage(), "SendFullSysMonStatus", "Sends the full System Monitor Status", ConsoleAccessLevelEnum.AccessOperator); @@ -72,18 +66,15 @@ namespace PepperDash.Essentials.AppServer.Messengers Debug.Console(1, "Posting System Monitor Status Message."); // This takes a while, launch a new thread - CrestronInvoke.BeginInvoke((o) => + CrestronInvoke.BeginInvoke(o => PostStatusMessage(new { - 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 - }); - }); + timeZone = SysMon.TimeZoneFeedback.IntValue, + timeZoneName = SysMon.TimeZoneTextFeedback.StringValue, + ioControllerVersion = SysMon.IoControllerVersionFeedback.StringValue, + snmpVersion = SysMon.SnmpVersionFeedback.StringValue, + bacnetVersion = SysMon.BaCnetAppVersionFeedback.StringValue, + controllerVersion = SysMon.ControllerVersionFeedback.StringValue + })); } protected override void CustomRegisterWithAppServer(MobileControlSystemController appServerController) diff --git a/PepperDashEssentials/Bridges/BridgeBase.cs b/PepperDashEssentials/Bridges/BridgeBase.cs index 4e814af9..03be4d7c 100644 --- a/PepperDashEssentials/Bridges/BridgeBase.cs +++ b/PepperDashEssentials/Bridges/BridgeBase.cs @@ -138,6 +138,11 @@ namespace PepperDash.Essentials.Bridges (device as GenericRelayDevice).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); continue; } + else if (device is IRSetTopBoxBase) + { + (device as IRSetTopBoxBase).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); + continue; + } else if (device is IDigitalInput) { (device as IDigitalInput).LinkToApi(Eisc, d.JoinStart, d.JoinMapKey); diff --git a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs index 23294997..e193cc2c 100644 --- a/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs +++ b/PepperDashEssentials/Bridges/DmChassisControllerBridge.cs @@ -1,284 +1,288 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.DM; - -using Newtonsoft.Json; - -namespace PepperDash.Essentials.Bridges -{ - public static class DmChassisControllerApiExtensions - { - public static void LinkToApi(this DmChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey) - { - DmChassisControllerJoinMap joinMap = new DmChassisControllerJoinMap(); - - var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); - - if (!string.IsNullOrEmpty(joinMapSerialized)) - joinMap = JsonConvert.DeserializeObject(joinMapSerialized); - - - joinMap.OffsetJoinNumbers(joinStart); - - Debug.Console(1, dmChassis, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); - - var chassis = dmChassis.Chassis as DmMDMnxn; - - dmChassis.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); - - trilist.SetUShortSigAction(joinMap.SystemId, new Action(o => chassis.SystemId.UShortValue = o)); - trilist.SetSigTrueAction(joinMap.SystemId, new Action(() => chassis.ApplySystemId())); - - dmChassis.SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId]); - dmChassis.SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId]); - - // Link up outputs - for (uint i = 1; i <= dmChassis.Chassis.NumberOfOutputs; i++) - { - var ioSlot = i; - - // Control - trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video))); - trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio))); - trilist.SetUShortSigAction(joinMap.OutputUsb + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput))); - trilist.SetUShortSigAction(joinMap.InputUsb + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput))); - - if (dmChassis.TxDictionary.ContainsKey(ioSlot)) - { - Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); - var txKey = dmChassis.TxDictionary[ioSlot]; - var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; - - var advancedTxDevice = basicTxDevice as DmTxControllerBase; - - if (dmChassis.Chassis is DmMd8x8Cpu3 || dmChassis.Chassis is DmMd8x8Cpu3rps - || dmChassis.Chassis is DmMd16x16Cpu3 || dmChassis.Chassis is DmMd16x16Cpu3rps - || dmChassis.Chassis is DmMd32x32Cpu3 || dmChassis.Chassis is DmMd32x32Cpu3rps) - { - dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); - } - else - { - if (advancedTxDevice != null) - { - advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); - Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); - } - else if (dmChassis.InputEndpointOnlineFeedbacks[ioSlot] != null) - { - Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); - dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); - } - } - - if (advancedTxDevice != null) // Advanced TX device - { - advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); - - // Flag if the TX is an advanced endpoint type - trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true; - } - else if(advancedTxDevice == null || basicTxDevice != null) // Basic TX device - { - Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); - dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); - - var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort != null) - { - Debug.Console(1, "Port value for input card {0} is set", ioSlot); - var port = inputPort.Port; - - if (port != null) - { - if (port is HdmiInputWithCEC) - { - Debug.Console(1, "Port is HdmiInputWithCec"); - - var hdmiInPortWCec = port as HdmiInputWithCEC; - - if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) - { - SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); - } - - dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); - - if(dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot]; - else - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; - } - } - } - else - { - inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; - - if(inputPort != null) - { - var port = inputPort.Port; - - if (port is DMInputPortWithCec) - { - Debug.Console(1, "Port is DMInputPortWithCec"); - - var dmInPortWCec = port as DMInputPortWithCec; - - if (dmInPortWCec != null) - { - SetHdcpStateAction(dmChassis.PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); - } - - dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); - - if (dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot]; - else - trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; - } - } - } - } - } - else - { - dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); - - var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; - if (inputPort != null) - { - var hdmiPort = inputPort.Port as EndpointHdmiInput; - - if (hdmiPort != null) - { - SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState + ioSlot, trilist); - dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); - } - } - } - if (dmChassis.RxDictionary.ContainsKey(ioSlot)) - { - Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); - var rxKey = dmChassis.RxDictionary[ioSlot]; - var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; - var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; - if (dmChassis.Chassis is DmMd8x8Cpu3 || dmChassis.Chassis is DmMd8x8Cpu3rps - || dmChassis.Chassis is DmMd16x16Cpu3 || dmChassis.Chassis is DmMd16x16Cpu3rps - || dmChassis.Chassis is DmMd32x32Cpu3 || dmChassis.Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) - { - dmChassis.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); - } - else if (rxDevice != null) - { - rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); - } - } - - // Feedback - dmChassis.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]); - dmChassis.AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]); - dmChassis.UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb + ioSlot]); - dmChassis.UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb + ioSlot]); - - - dmChassis.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]); - dmChassis.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]); - dmChassis.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]); - dmChassis.OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]); - } - } - - static void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) - { - if (hdcpTypeSimple) - { - trilist.SetUShortSigAction(join, - new Action(s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - })); - } - else - { - trilist.SetUShortSigAction(join, - new Action(u => - { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - })); - } - } - - static void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) - { - if (hdcpTypeSimple) - { - trilist.SetUShortSigAction(join, - new Action(s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - })); - } - else - { - trilist.SetUShortSigAction(join, - new Action(u => - { - port.HdcpCapability = (eHdcpCapabilityType)u; - })); - } - } - - static void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) - { - if (!supportsHdcp2) - { - trilist.SetUShortSigAction(join, - new Action(s => - { - if (s == 0) - { - port.HdcpSupportOff(); - } - else if (s > 0) - { - port.HdcpSupportOn(); - } - })); - } - else - { - trilist.SetUShortSigAction(join, - new Action(u => - { - port.HdcpReceiveCapability = (eHdcpCapabilityType)u; - })); - } - } - - } + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Endpoints; +using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.DM; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Bridges +{ + public static class DmChassisControllerApiExtentions + { + public static void LinkToApi(this DmChassisController dmChassis, BasicTriList trilist, uint joinStart, string joinMapKey) + { + DmChassisControllerJoinMap joinMap = new DmChassisControllerJoinMap(); + + var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, dmChassis, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + + var chassis = dmChassis.Chassis as DmMDMnxn; + + dmChassis.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + + trilist.SetUShortSigAction(joinMap.SystemId, new Action(o => chassis.SystemId.UShortValue = o)); + trilist.SetSigTrueAction(joinMap.SystemId, new Action(() => chassis.ApplySystemId())); + + dmChassis.SystemIdFeebdack.LinkInputSig(trilist.UShortInput[joinMap.SystemId]); + dmChassis.SystemIdBusyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SystemId]); + + // Link up outputs + for (uint i = 1; i <= dmChassis.Chassis.NumberOfOutputs; i++) + { + var ioSlot = i; + + // Control + trilist.SetUShortSigAction(joinMap.OutputVideo + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video))); + trilist.SetUShortSigAction(joinMap.OutputAudio + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio))); + trilist.SetUShortSigAction(joinMap.OutputUsb + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbOutput))); + trilist.SetUShortSigAction(joinMap.InputUsb + ioSlot, new Action(o => dmChassis.ExecuteSwitch(o, ioSlot, eRoutingSignalType.UsbInput))); + + if (dmChassis.TxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot); + var txKey = dmChassis.TxDictionary[ioSlot]; + var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase; + + var advancedTxDevice = basicTxDevice as DmTxControllerBase; + + if (dmChassis.Chassis is DmMd8x8Cpu3 || dmChassis.Chassis is DmMd8x8Cpu3rps + || dmChassis.Chassis is DmMd16x16Cpu3 || dmChassis.Chassis is DmMd16x16Cpu3rps + || dmChassis.Chassis is DmMd32x32Cpu3 || dmChassis.Chassis is DmMd32x32Cpu3rps) + { + dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + else + { + if (advancedTxDevice != null) + { + advancedTxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + Debug.Console(2, "Linking Tx Online Feedback from Advanced Transmitter at input {0}", ioSlot); + } + else if (dmChassis.InputEndpointOnlineFeedbacks[ioSlot] != null) + { + Debug.Console(2, "Linking Tx Online Feedback from Input Card {0}", ioSlot); + dmChassis.InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.InputEndpointOnline + ioSlot]); + } + } + + if (basicTxDevice != null && advancedTxDevice == null) + trilist.BooleanInput[joinMap.TxAdvancedIsPresent + ioSlot].BoolValue = true; + + if (advancedTxDevice != null) + { + advancedTxDevice.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + } + else if(advancedTxDevice == null || basicTxDevice != null) + { + Debug.Console(1, "Setting up actions and feedbacks on input card {0}", ioSlot); + dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + Debug.Console(1, "Port value for input card {0} is set", ioSlot); + var port = inputPort.Port; + + if (port != null) + { + if (port is HdmiInputWithCEC) + { + Debug.Console(1, "Port is HdmiInputWithCec"); + + var hdmiInPortWCec = port as HdmiInputWithCEC; + + if (hdmiInPortWCec.HdcpSupportedLevel != eHdcpSupportedLevel.Unknown) + { + SetHdcpStateAction(true, hdmiInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); + } + + dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + + if(dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; + } + } + } + else + { + inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)]; + + if(inputPort != null) + { + var port = inputPort.Port; + + if (port is DMInputPortWithCec) + { + Debug.Console(1, "Port is DMInputPortWithCec"); + + var dmInPortWCec = port as DMInputPortWithCec; + + if (dmInPortWCec != null) + { + SetHdcpStateAction(dmChassis.PropertiesConfig.InputSlotSupportsHdcp2[ioSlot], dmInPortWCec, joinMap.HdcpSupportState + ioSlot, trilist); + } + + dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + + if (dmChassis.InputCardHdcpCapabilityTypes.ContainsKey(ioSlot)) + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = (ushort)dmChassis.InputCardHdcpCapabilityTypes[ioSlot]; + else + trilist.UShortInput[joinMap.HdcpSupportCapability + ioSlot].UShortValue = 1; + } + } + } + } + } + else + { + dmChassis.VideoInputSyncFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus + ioSlot]); + + var inputPort = dmChassis.InputPorts[string.Format("inputCard{0}--hdmiIn", ioSlot)]; + if (inputPort != null) + { + var hdmiPort = inputPort.Port as EndpointHdmiInput; + + if (hdmiPort != null) + { + SetHdcpStateAction(true, hdmiPort, joinMap.HdcpSupportState + ioSlot, trilist); + dmChassis.InputCardHdcpCapabilityFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.HdcpSupportState + ioSlot]); + } + } + } + + if (dmChassis.RxDictionary.ContainsKey(ioSlot)) + { + Debug.Console(2, "Creating Rx Feedbacks {0}", ioSlot); + var rxKey = dmChassis.RxDictionary[ioSlot]; + var rxDevice = DeviceManager.GetDeviceForKey(rxKey) as DmRmcControllerBase; + var hdBaseTDevice = DeviceManager.GetDeviceForKey(rxKey) as DmHdBaseTControllerBase; + if (dmChassis.Chassis is DmMd8x8Cpu3 || dmChassis.Chassis is DmMd8x8Cpu3rps + || dmChassis.Chassis is DmMd16x16Cpu3 || dmChassis.Chassis is DmMd16x16Cpu3rps + || dmChassis.Chassis is DmMd32x32Cpu3 || dmChassis.Chassis is DmMd32x32Cpu3rps || hdBaseTDevice != null) + { + dmChassis.OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + } + else if (rxDevice != null) + { + rxDevice.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.OutputEndpointOnline + ioSlot]); + } + } + + // Feedback + dmChassis.VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo + ioSlot]); + dmChassis.AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio + ioSlot]); + dmChassis.UsbOutputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputUsb + ioSlot]); + dmChassis.UsbInputRoutedToFeebacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.InputUsb + ioSlot]); + + dmChassis.OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames + ioSlot]); + dmChassis.InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames + ioSlot]); + dmChassis.OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames + ioSlot]); + dmChassis.OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames + ioSlot]); + + dmChassis.OutputDisabledByHdcpFeedbacks[ioSlot].LinkInputSig(trilist.BooleanInput[joinMap.OutputDisabledByHdcp + ioSlot]); + } + } + + static void SetHdcpStateAction(bool hdcpTypeSimple, HdmiInputWithCEC port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + new Action(s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + })); + } + else + { + trilist.SetUShortSigAction(join, + new Action(u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + })); + } + } + + static void SetHdcpStateAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist) + { + if (hdcpTypeSimple) + { + trilist.SetUShortSigAction(join, + new Action(s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + })); + } + else + { + trilist.SetUShortSigAction(join, + new Action(u => + { + port.HdcpCapability = (eHdcpCapabilityType)u; + })); + } + } + + static void SetHdcpStateAction(bool supportsHdcp2, DMInputPortWithCec port, uint join, BasicTriList trilist) + { + if (!supportsHdcp2) + { + trilist.SetUShortSigAction(join, + new Action(s => + { + if (s == 0) + { + port.HdcpSupportOff(); + } + else if (s > 0) + { + port.HdcpSupportOn(); + } + })); + } + else + { + trilist.SetUShortSigAction(join, + new Action(u => + { + port.HdcpReceiveCapability = (eHdcpCapabilityType)u; + })); + } + } + + } + } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs b/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs index 44250f4c..d905beef 100644 --- a/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs +++ b/PepperDashEssentials/Bridges/GlsOccupancySensorBaseControllerBridge.cs @@ -31,6 +31,16 @@ namespace PepperDash.Essentials.Bridges #region Single and Dual Sensor Stuff occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline]); + trilist.StringInput[joinMap.Name].StringValue = occController.Name; + + trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) => + { + if (args.DeviceOnLine) + { + trilist.StringInput[joinMap.Name].StringValue = occController.Name; + } + } + ); // Occupied status trilist.SetSigTrueAction(joinMap.ForceOccupied, new Action(() => occController.ForceOccupied())); @@ -38,6 +48,7 @@ namespace PepperDash.Essentials.Bridges occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback]); occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback]); occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback]); + trilist.SetBoolSigAction(joinMap.EnableRawStates, new Action((b) => occController.EnableRawStates(b))); // Timouts trilist.SetUShortSigAction(joinMap.Timeout, new Action((u) => occController.SetRemoteTimeout(u))); diff --git a/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs b/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs new file mode 100644 index 00000000..68d765bc --- /dev/null +++ b/PepperDashEssentials/Bridges/IRSetTopBoxBaseBridge.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common; + +using Newtonsoft.Json; + +namespace PepperDash.Essentials.Bridges +{ + public static class IRSetTopBoxBaseApiExtensions + { + public static void LinkToApi(this PepperDash.Essentials.Devices.Common.IRSetTopBoxBase stbDevice, BasicTriList trilist, uint joinStart, string joinMapKey) + { + SetTopBoxControllerJoinMap joinMap = new SetTopBoxControllerJoinMap(); + var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); + + if (!string.IsNullOrEmpty(joinMapSerialized)) + joinMap = JsonConvert.DeserializeObject(joinMapSerialized); + + joinMap.OffsetJoinNumbers(joinStart); + + Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); + Debug.Console(0, "Linking to Display: {0}", stbDevice.Name); + + trilist.StringInput[joinMap.Name].StringValue = stbDevice.Name; + + var stbBase = stbDevice as ISetTopBoxControls; + if (stbBase != null) + { + trilist.BooleanInput[joinMap.HasDpad].BoolValue = stbBase.HasDpad; + trilist.BooleanInput[joinMap.HasNumeric].BoolValue = stbBase.HasNumeric; + trilist.BooleanInput[joinMap.HasDvr].BoolValue = stbBase.HasDvr; + trilist.BooleanInput[joinMap.HasPresets].BoolValue = stbBase.HasPresets; + + trilist.SetBoolSigAction(joinMap.DvrList, (b) => stbBase.DvrList(b)); + trilist.SetBoolSigAction(joinMap.Replay, (b) => stbBase.Replay(b)); + + trilist.SetStringSigAction(joinMap.LoadPresets, (s) => stbBase.LoadPresets(s)); + } + + var stbPower = stbDevice as IPower; + if (stbPower != null) + { + trilist.SetSigTrueAction(joinMap.PowerOn, () => stbPower.PowerOn()); + trilist.SetSigTrueAction(joinMap.PowerOff, () => stbPower.PowerOff()); + trilist.SetSigTrueAction(joinMap.PowerToggle, () => stbPower.PowerToggle()); + + } + + var stbDPad = stbDevice as IDPad; + if (stbDPad != null) + { + trilist.SetBoolSigAction(joinMap.Up, (b) => stbDPad.Up(b)); + trilist.SetBoolSigAction(joinMap.Down, (b) => stbDPad.Down(b)); + trilist.SetBoolSigAction(joinMap.Left, (b) => stbDPad.Left(b)); + trilist.SetBoolSigAction(joinMap.Right, (b) => stbDPad.Right(b)); + trilist.SetBoolSigAction(joinMap.Select, (b) => stbDPad.Select(b)); + trilist.SetBoolSigAction(joinMap.Menu, (b) => stbDPad.Menu(b)); + trilist.SetBoolSigAction(joinMap.Exit, (b) => stbDPad.Exit(b)); + } + + var stbChannel = stbDevice as IChannel; + if (stbChannel != null) + { + trilist.SetBoolSigAction(joinMap.ChannelUp, (b) => stbChannel.ChannelUp(b)); + trilist.SetBoolSigAction(joinMap.ChannelDown, (b) => stbChannel.ChannelDown(b)); + trilist.SetBoolSigAction(joinMap.LastChannel, (b) => stbChannel.LastChannel(b)); + trilist.SetBoolSigAction(joinMap.Guide, (b) => stbChannel.Guide(b)); + trilist.SetBoolSigAction(joinMap.Info, (b) => stbChannel.Info(b)); + trilist.SetBoolSigAction(joinMap.Exit, (b) => stbChannel.Exit(b)); + } + + var stbColor = stbDevice as IColor; + if (stbColor != null) + { + trilist.SetBoolSigAction(joinMap.Red, (b) => stbColor.Red(b)); + trilist.SetBoolSigAction(joinMap.Green, (b) => stbColor.Green(b)); + trilist.SetBoolSigAction(joinMap.Yellow, (b) => stbColor.Yellow(b)); + trilist.SetBoolSigAction(joinMap.Blue, (b) => stbColor.Blue(b)); + } + + var stbKeypad = stbDevice as ISetTopBoxNumericKeypad; + if (stbKeypad != null) + { + trilist.StringInput[joinMap.KeypadAccessoryButton1Label].StringValue = stbKeypad.KeypadAccessoryButton1Label; + trilist.StringInput[joinMap.KeypadAccessoryButton2Label].StringValue = stbKeypad.KeypadAccessoryButton2Label; + + trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1].BoolValue = stbKeypad.HasKeypadAccessoryButton1; + trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2].BoolValue = stbKeypad.HasKeypadAccessoryButton2; + + trilist.SetBoolSigAction(joinMap.Digit0, (b) => stbKeypad.Digit0(b)); + trilist.SetBoolSigAction(joinMap.Digit1, (b) => stbKeypad.Digit1(b)); + trilist.SetBoolSigAction(joinMap.Digit2, (b) => stbKeypad.Digit2(b)); + trilist.SetBoolSigAction(joinMap.Digit3, (b) => stbKeypad.Digit3(b)); + trilist.SetBoolSigAction(joinMap.Digit4, (b) => stbKeypad.Digit4(b)); + trilist.SetBoolSigAction(joinMap.Digit5, (b) => stbKeypad.Digit5(b)); + trilist.SetBoolSigAction(joinMap.Digit6, (b) => stbKeypad.Digit6(b)); + trilist.SetBoolSigAction(joinMap.Digit7, (b) => stbKeypad.Digit7(b)); + trilist.SetBoolSigAction(joinMap.Digit8, (b) => stbKeypad.Digit8(b)); + trilist.SetBoolSigAction(joinMap.Digit9, (b) => stbKeypad.Digit9(b)); + trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press, (b) => stbKeypad.KeypadAccessoryButton1(b)); + trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press, (b) => stbKeypad.KeypadAccessoryButton1(b)); + trilist.SetBoolSigAction(joinMap.Dash, (b) => stbKeypad.Dash(b)); + trilist.SetBoolSigAction(joinMap.KeypadEnter, (b) => stbKeypad.KeypadEnter(b)); + } + + var stbTransport = stbDevice as ITransport; + if (stbTransport != null) + { + trilist.SetBoolSigAction(joinMap.Play, (b) => stbTransport.Play(b)); + trilist.SetBoolSigAction(joinMap.Pause, (b) => stbTransport.Pause(b)); + trilist.SetBoolSigAction(joinMap.Rewind, (b) => stbTransport.Rewind(b)); + trilist.SetBoolSigAction(joinMap.FFwd, (b) => stbTransport.FFwd(b)); + trilist.SetBoolSigAction(joinMap.ChapMinus, (b) => stbTransport.ChapMinus(b)); + trilist.SetBoolSigAction(joinMap.ChapPlus, (b) => stbTransport.ChapPlus(b)); + trilist.SetBoolSigAction(joinMap.Stop, (b) => stbTransport.Stop(b)); + trilist.SetBoolSigAction(joinMap.Record, (b) => stbTransport.Record(b)); + + } + + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs index 7c920cc4..ff6a42d9 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/DmChassisControllerJoinMap.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -38,6 +38,10 @@ namespace PepperDash.Essentials.Bridges /// Range reports high if corresponding input's transmitter supports bridging as a separate device for detailed AV switching, HDCP control, etc. /// public uint TxAdvancedIsPresent { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with + /// + /// Range reports high if corresponding output is disabled by HDCP. + /// + public uint OutputDisabledByHdcp { get; set; } // indicates that there is an attached transmitter that should be bridged to be interacted with #endregion #region Analogs @@ -101,6 +105,7 @@ namespace PepperDash.Essentials.Bridges InputEndpointOnline = 500; //501-699 OutputEndpointOnline = 700; //701-899 TxAdvancedIsPresent = 1000; //1001-1199 + OutputDisabledByHdcp = 1200; //1201-1399 //Analog OutputVideo = 100; //101-299 @@ -139,6 +144,7 @@ namespace PepperDash.Essentials.Bridges OutputEndpointOnline = OutputEndpointOnline + joinOffset; HdcpSupportState = HdcpSupportState + joinOffset; HdcpSupportCapability = HdcpSupportCapability + joinOffset; + OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset; TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset; } } diff --git a/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs index a48ad0d9..6e19dff2 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/GlsOccupancySensorBaseJoinMap.cs @@ -137,6 +137,10 @@ namespace PepperDash.Essentials.Bridges public uint PirSensitivityInVacantState { get; set; } #endregion + #region Serial + public uint Name { get; set; } + #endregion + public GlsOccupancySensorBaseJoinMap() { IsOnline = 1; @@ -177,7 +181,10 @@ namespace PepperDash.Essentials.Bridges UsSensitivityInOccupiedState = 5; UsSensitivityInVacantState = 6; PirSensitivityInOccupiedState = 7; - PirSensitivityInVacantState = 8; + PirSensitivityInVacantState = 8; + + Name = 1; + } public override void OffsetJoinNumbers(uint joinStart) @@ -206,7 +213,6 @@ namespace PepperDash.Essentials.Bridges DisableUsB = DisableUsB + joinOffset; EnablePir = EnablePir + joinOffset; DisablePir = DisablePir + joinOffset; - DisablePir = DisablePir + joinOffset; IncrementUsInOccupiedState = IncrementUsInOccupiedState + joinOffset; DecrementUsInOccupiedState = DecrementUsInOccupiedState + joinOffset; IncrementUsInVacantState = IncrementUsInVacantState + joinOffset; @@ -224,6 +230,8 @@ namespace PepperDash.Essentials.Bridges UsSensitivityInVacantState = UsSensitivityInVacantState + joinOffset; PirSensitivityInOccupiedState = PirSensitivityInOccupiedState + joinOffset; PirSensitivityInVacantState = PirSensitivityInVacantState + joinOffset; + + Name = Name + joinOffset; } } diff --git a/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs new file mode 100644 index 00000000..aa23cb7a --- /dev/null +++ b/PepperDashEssentials/Bridges/JoinMaps/SetTopBoxControllerJoinMap.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using PepperDash.Essentials.Core; +using Crestron.SimplSharp.Reflection; + + +namespace PepperDash.Essentials.Bridges +{ + public class SetTopBoxControllerJoinMap : JoinMapBase + { + #region Digitals + public uint DvrList { get; set; } // + public uint Replay { get; set; } + public uint Up { get; set; } // + public uint Down { get; set; } // + public uint Left { get; set; } // + public uint Right { get; set; } // + public uint Select { get; set; } // + public uint Menu { get; set; } // + public uint Exit { get; set; } // + public uint Digit0 { get; set; } // + public uint Digit1 { get; set; } // + public uint Digit2 { get; set; } // + public uint Digit3 { get; set; } // + public uint Digit4 { get; set; } // + public uint Digit5 { get; set; } // + public uint Digit6 { get; set; } // + public uint Digit7 { get; set; } // + public uint Digit8 { get; set; } // + public uint Digit9 { get; set; } // + public uint Dash { get; set; } // + public uint KeypadEnter { get; set; } // + public uint ChannelUp { get; set; } // + public uint ChannelDown { get; set; } // + public uint LastChannel { get; set; } // + public uint Guide { get; set; } // + public uint Info { get; set; } // + public uint Red { get; set; } // + public uint Green { get; set; } // + public uint Yellow { get; set; } // + public uint Blue { get; set; } // + public uint ChapMinus { get; set; } + public uint ChapPlus { get; set; } + public uint FFwd { get; set; } // + public uint Pause { get; set; } // + public uint Play { get; set; } // + public uint Record { get; set; } + public uint Rewind { get; set; } // + public uint Stop { get; set; } // + + public uint PowerOn { get; set; } // + public uint PowerOff { get; set; } // + public uint PowerToggle { get; set; } // + + public uint HasKeypadAccessoryButton1 { get; set; } + public uint HasKeypadAccessoryButton2 { get; set; } + + public uint KeypadAccessoryButton1Press { get; set; } + public uint KeypadAccessoryButton2Press { get; set; } + + + public uint HasDvr { get; set; } + public uint HasPresets { get; set; } + public uint HasNumeric { get; set; } + public uint HasDpad { get; set; } + + + #endregion + + #region Analogs + + #endregion + + #region Strings + public uint Name { get; set; } + public uint LoadPresets { get; set; } + public uint KeypadAccessoryButton1Label { get; set; } + public uint KeypadAccessoryButton2Label { get; set; } + + #endregion + + public SetTopBoxControllerJoinMap() + { + PowerOn = 1; + PowerOff = 2; + PowerToggle = 3; + + HasDpad = 4; + Up = 4; + Down = 5; + Left = 6; + Right = 7; + Select = 8; + Menu = 9; + Exit = 10; + + HasNumeric = 11; + Digit0 = 11; + Digit1 = 12; + Digit2 = 13; + Digit3 = 14; + Digit4 = 15; + Digit5 = 16; + Digit6 = 17; + Digit7 = 18; + Digit8 = 19; + Digit9 = 20; + Dash = 21; + KeypadEnter = 22; + ChannelUp = 23; + ChannelDown = 24; + LastChannel = 25; + + Guide = 26; + Info = 27; + Red = 28; + Green = 29; + Yellow = 30; + Blue = 31; + + HasDvr = 32; + DvrList = 32; + Play = 33; + Pause = 34; + Stop = 35; + FFwd = 36; + Rewind = 37; + ChapPlus = 38; + ChapMinus = 39; + Replay = 40; + Record = 41; + HasKeypadAccessoryButton1 = 42; + KeypadAccessoryButton1Press = 42; + HasKeypadAccessoryButton2 = 43; + KeypadAccessoryButton2Press = 43; + + Name = 1; + KeypadAccessoryButton1Label = 42; + KeypadAccessoryButton2Label = 43; + + LoadPresets = 50; + } + + public override void OffsetJoinNumbers(uint joinStart) + { + var joinOffset = joinStart - 1; + + PowerOn += joinOffset; + PowerOff += joinOffset; + PowerToggle += joinOffset; + + HasDpad += joinOffset; + Up += joinOffset; + Down += joinOffset; + Left += joinOffset; + Right += joinOffset; + Select += joinOffset; + Menu += joinOffset; + Exit += joinOffset; + + HasNumeric += joinOffset; + Digit0 += joinOffset; + Digit1 += joinOffset; + Digit2 += joinOffset; + Digit3 += joinOffset; + Digit4 += joinOffset; + Digit5 += joinOffset; + Digit6 += joinOffset; + Digit7 += joinOffset; + Digit8 += joinOffset; + Digit9 += joinOffset; + Dash += joinOffset; + KeypadEnter += joinOffset; + ChannelUp += joinOffset; + ChannelDown += joinOffset; + LastChannel += joinOffset; + + Guide += joinOffset; + Info += joinOffset; + Red += joinOffset; + Green += joinOffset; + Yellow += joinOffset; + Blue += joinOffset; + + HasDvr += joinOffset; + DvrList += joinOffset; + Play += joinOffset; + Pause += joinOffset; + Stop += joinOffset; + FFwd += joinOffset; + Rewind += joinOffset; + ChapPlus += joinOffset; + ChapMinus += joinOffset; + Replay += joinOffset; + Record += joinOffset; + HasKeypadAccessoryButton1 += joinOffset; + KeypadAccessoryButton1Press += joinOffset; + HasKeypadAccessoryButton2 += joinOffset; + KeypadAccessoryButton2Press += joinOffset; + + Name += joinOffset; + KeypadAccessoryButton1Label += joinOffset; + KeypadAccessoryButton2Label += joinOffset; + + LoadPresets += joinOffset; + } + + } +} \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs b/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs index 6358700f..b2b66263 100644 --- a/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs +++ b/PepperDashEssentials/Bridges/JoinMaps/SystemMonitorJoinMap.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core; namespace PepperDash.Essentials.Bridges { @@ -14,11 +9,21 @@ namespace PepperDash.Essentials.Bridges /// public uint ProgramStartJoin { get; set; } + /// + /// Offset to indicate where the range of iterated Ethernet joins will start + /// + public uint EthernetStartJoin { get; set; } + /// /// Offset between each program join set /// public uint ProgramOffsetJoin { get; set; } + /// + /// Offset between each Ethernet Interface join set + /// + public uint EthernetOffsetJoin { get; set; } + #region Digitals /// /// Range Sets and reports whether the corresponding program slot is started @@ -87,6 +92,68 @@ namespace PepperDash.Essentials.Bridges /// Serialized JSON output that aggregates the program info of the corresponding program /// public uint AggregatedProgramInfo { get; set; } + /// + /// Reports the controller serial number + /// + public uint SerialNumber { get; set; } + /// + /// Reports the controller model + /// + public uint Model { get; set; } + /// + /// Reports the Host name set on the corresponding interface + /// + public uint HostName { get; set; } + /// + /// Reports the Current IP address set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned address. + /// + public uint CurrentIpAddress { get; set; } + /// + /// Reporst the Current Default Gateway set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned gateway + /// + public uint CurrentDefaultGateway { get; set; } + /// + /// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask + /// + public uint CurrentSubnetMask { get; set; } + /// + /// Reports the Static IP address set on the corresponding interface. If DHCP is disabled, this will match the Current IP address + /// + public uint StaticIpAddress { get; set; } + /// + /// Reporst the Static Default Gateway set on the corresponding interface. If DHCP is disabled, this will match the Current gateway + /// + public uint StaticDefaultGateway { get; set; } + /// + /// Reports the Current Subnet Mask set on the corresponding interface. If DHCP is enabled, this will be the DHCP assigned subnet mask + /// + public uint StaticSubnetMask { get; set; } + /// + /// Reports the current DomainFeedback on the corresponding interface + /// + public uint Domain { get; set; } + /// + /// Reports the current DNS Servers on the corresponding interface + /// + public uint DnsServer { get; set; } + /// + /// Reports the MAC Address of the corresponding interface + /// + public uint MacAddress { get; set; } + /// + /// Reports the DHCP Status of the corresponding interface + /// + public uint DhcpStatus { get; set; } + + /// + /// Reports the current uptime. Updated in 5 minute intervals. + /// + public uint Uptime { get; set; } + + /// + /// Reports the date of the last boot + /// + public uint LastBoot { get; set; } #endregion public SystemMonitorJoinMap() @@ -98,6 +165,10 @@ namespace PepperDash.Essentials.Bridges SnmpAppVersion = 3; BACnetAppVersion = 4; ControllerVersion = 5; + SerialNumber = 6; + Model = 7; + Uptime = 8; + LastBoot = 9; ProgramStartJoin = 10; @@ -115,6 +186,23 @@ namespace PepperDash.Essentials.Bridges ProgramCrestronDatabaseVersion = 3; ProgramEnvironmentVersion = 4; AggregatedProgramInfo = 5; + + EthernetStartJoin = 75; + + EthernetOffsetJoin = 15; + + // Offset in groups of 15 + HostName = 1; + CurrentIpAddress = 2; + CurrentSubnetMask = 3; + CurrentDefaultGateway = 4; + StaticIpAddress = 5; + StaticSubnetMask = 6; + StaticDefaultGateway = 7; + Domain = 8; + DnsServer = 9; + MacAddress = 10; + DhcpStatus = 11; } public override void OffsetJoinNumbers(uint joinStart) @@ -131,6 +219,7 @@ namespace PepperDash.Essentials.Bridges // Sets the initial join value where the iterated program joins will begin ProgramStartJoin = ProgramStartJoin + joinOffset; + EthernetStartJoin = EthernetStartJoin + joinOffset; } } } \ No newline at end of file diff --git a/PepperDashEssentials/Bridges/SystemMonitorBridge.cs b/PepperDashEssentials/Bridges/SystemMonitorBridge.cs index 4e66ea08..6e41a43f 100644 --- a/PepperDashEssentials/Bridges/SystemMonitorBridge.cs +++ b/PepperDashEssentials/Bridges/SystemMonitorBridge.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.Diagnostics; using PepperDash.Core; using PepperDash.Essentials.Core; @@ -17,7 +12,7 @@ namespace PepperDash.Essentials.Bridges { public static void LinkToApi(this SystemMonitorController systemMonitorController, BasicTriList trilist, uint joinStart, string joinMapKey) { - SystemMonitorJoinMap joinMap = new SystemMonitorJoinMap(); + var joinMap = new SystemMonitorJoinMap(); var joinMapSerialized = JoinMapHelper.GetJoinMapForDevice(joinMapKey); @@ -30,36 +25,71 @@ namespace PepperDash.Essentials.Bridges Debug.Console(2, systemMonitorController, "Linking API starting at join: {0}", joinStart); systemMonitorController.TimeZoneFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeZone]); - //trilist.SetUShortSigAction(joinMap.TimeZone, new Action(u => systemMonitorController.SetTimeZone(u))); systemMonitorController.TimeZoneTextFeedback.LinkInputSig(trilist.StringInput[joinMap.TimeZoneName]); - systemMonitorController.IOControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]); + systemMonitorController.IoControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.IOControllerVersion]); systemMonitorController.SnmpVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.SnmpAppVersion]); - systemMonitorController.BACnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]); + systemMonitorController.BaCnetAppVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.BACnetAppVersion]); systemMonitorController.ControllerVersionFeedback.LinkInputSig(trilist.StringInput[joinMap.ControllerVersion]); + systemMonitorController.SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumber]); + systemMonitorController.ModelFeedback.LinkInputSig(trilist.StringInput[joinMap.Model]); + systemMonitorController.UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime]); + systemMonitorController.LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot]); // iterate the program status feedback collection and map all the joins + LinkProgramInfoJoins(systemMonitorController, trilist, joinMap); + + LinkEthernetInfoJoins(systemMonitorController, trilist, joinMap); + } + + private static void LinkEthernetInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, SystemMonitorJoinMap joinMap) + { + var ethernetSlotJoinStart = joinMap.EthernetStartJoin; + + foreach (var fb in systemMonitorController.EthernetStatusFeedbackCollection) + { + fb.Value.CurrentIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentIpAddress]); + fb.Value.CurrentSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentSubnetMask]); + fb.Value.CurrentDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.CurrentDefaultGateway]); + fb.Value.StaticIpAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticIpAddress]); + fb.Value.StaticSubnetMaskFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticSubnetMask]); + fb.Value.StaticDefaultGatewayFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.StaticDefaultGateway]); + fb.Value.HostNameFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.HostName]); + fb.Value.MacAddressFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.MacAddress]); + fb.Value.DomainFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.Domain]); + fb.Value.DnsServerFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DnsServer]); + fb.Value.DhcpStatusFeedback.LinkInputSig(trilist.StringInput[ethernetSlotJoinStart + joinMap.DhcpStatus]); + + ethernetSlotJoinStart += joinMap.EthernetOffsetJoin; + } + } + + private static void LinkProgramInfoJoins(SystemMonitorController systemMonitorController, BasicTriList trilist, + SystemMonitorJoinMap joinMap) + { var programSlotJoinStart = joinMap.ProgramStartJoin; foreach (var p in systemMonitorController.ProgramStatusFeedbackCollection) { var programNumber = p.Value.Program.Number; - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, new Action - (b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start)); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStart, + b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Start); p.Value.ProgramStartedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStart]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, new Action - (b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop)); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramStop, + b => SystemMonitor.ProgramCollection[programNumber].OperatingState = eProgramOperatingState.Stop); p.Value.ProgramStoppedFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramStop]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, new Action - (b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register)); - p.Value.ProgramRegisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramRegister, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Register); + p.Value.ProgramRegisteredFeedback.LinkInputSig( + trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramRegister]); - trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, new Action - (b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister)); - p.Value.ProgramUnregisteredFeedback.LinkInputSig(trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]); + trilist.SetBoolSigAction(programSlotJoinStart + joinMap.ProgramUnregister, + b => SystemMonitor.ProgramCollection[programNumber].RegistrationState = eProgramRegistrationState.Unregister); + p.Value.ProgramUnregisteredFeedback.LinkInputSig( + trilist.BooleanInput[programSlotJoinStart + joinMap.ProgramUnregister]); p.Value.ProgramNameFeedback.LinkInputSig(trilist.StringInput[programSlotJoinStart + joinMap.ProgramName]); p.Value.ProgramCompileTimeFeedback.LinkInputSig( diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index a88d932b..46ac77f2 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -25,6 +25,7 @@ namespace PepperDash.Essentials { HttpLogoServer LogoServer; + public ControlSystem() : base() { @@ -46,6 +47,8 @@ namespace PepperDash.Essentials ConsoleAccessLevelEnum.AccessOperator); } + CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator); + // CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(s => { @@ -78,10 +81,12 @@ namespace PepperDash.Essentials GoWithLoad(); } + + /// /// Determines if the program is running on a processor (appliance) or server (VC-4). /// - /// Sets Global.FilePathPrefix based on platform + /// Sets Global.FilePathPrefix and Global.ApplicationDirectoryPathPrefix based on platform /// public void DeterminePlatform() { @@ -108,7 +113,7 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion); // Check if User/ProgramX exists - if (Directory.Exists(directoryPrefix + dirSeparator + "User" + if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User" + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) { Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber); @@ -158,11 +163,13 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration"); + PluginLoader.AddProgramAssemblies(); + var filesReady = SetupFilesystem(); if (filesReady) { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins"); - LoadPlugins(); + PluginLoader.LoadPlugins(); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config..."); if (!ConfigReader.LoadConfig2()) @@ -197,118 +204,7 @@ namespace PepperDash.Essentials } - /// - /// Initial simple implementation. Reads user/programXX/plugins folder and - /// use - /// - void LoadPlugins() - { - var dir = Global.FilePathPrefix + "plugins"; - if (Directory.Exists(dir)) - { - // TODO Clear out or create localPlugins folder (maybe in program slot folder) - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for factory plugins"); - var di = new DirectoryInfo(dir); - var zFiles = di.GetFiles("*.cplz"); - foreach (var fi in zFiles) - { - Debug.Console(0, "Found cplz: {0}. Unzipping into plugins directory", fi.Name); - var result = CrestronZIP.Unzip(fi.FullName, di.FullName); - Debug.Console(0, "UnZip Result: {0}", result.ToString()); - fi.Delete(); - } - var files = di.GetFiles("*.dll"); - Dictionary assyList = new Dictionary(); - foreach (FileInfo fi in files) - { - // TODO COPY plugin to loadedPlugins folder - // TODO LOAD that loadedPlugins dll file - try - { - var assy = Assembly.LoadFrom(fi.FullName); - var ver = assy.GetName().Version; - var verStr = string.Format("{0}.{1}.{2}.{3}", ver.Major, ver.Minor, ver.Build, ver.Revision); - assyList.Add(fi.FullName, assy); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded plugin file '{0}', version {1}", fi.FullName, verStr); - } - catch - { - Debug.Console(2, "Assembly {0} is not a custom assembly", fi.FullName); - continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here - } - } - foreach (var assy in assyList) - { - // iteratate this assembly's classes, looking for "LoadPlugin()" methods - try - { - var types = assy.Value.GetTypes(); - foreach (var type in types) - { - try - { - var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); - var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); - if (loadPlugin != null) - { - Debug.Console(2, "LoadPlugin method found in {0}", type.Name); - - var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); - - var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion")); - if (minimumVersion != null) - { - Debug.Console(2, "MinimumEssentialsFrameworkVersion found"); - - var minimumVersionString = minimumVersion.GetValue(null) as string; - - if (!string.IsNullOrEmpty(minimumVersionString)) - { - var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString); - - if (!passed) - { - Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString); - continue; - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString); - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary."); - } - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary."); - } - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding plugin: {0}", assy.Key); - loadPlugin.Invoke(null, null); - } - } - catch - { - Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly", assy.Value.FullName); - continue; - } - - } - } - catch - { - Debug.Console(2, "Assembly {0} is not a custom assembly. Types cannot be loaded.", assy.Value.FullName); - continue; - } - } - // plugin dll will be loaded. Any classes in plugin should have a static constructor - // that registers that class with the Core.DeviceFactory - } - } + /// /// Verifies filesystem is set up. IR, SGD, and programX folders @@ -428,11 +324,30 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(dmpsRoutingController); } + else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1) + { + Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController."); + + var butToken = devConf.Properties["buttons"]; + if (butToken != null) + { + var buttons = butToken.ToObject>(); + var tpController = new Essentials.Core.Touchpanels.Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons); + DeviceManager.AddDevice(tpController); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key); + } + + } else { Debug.Console(2, "************Processor is not DMPS type***************"); } + + continue; } diff --git a/PepperDashEssentials/HttpApiHandler.cs b/PepperDashEssentials/HttpApiHandler.cs deleted file mode 100644 index 0a757999..00000000 --- a/PepperDashEssentials/HttpApiHandler.cs +++ /dev/null @@ -1,266 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using Crestron.SimplSharp; -//using Crestron.SimplSharp.CrestronIO; -//using Crestron.SimplSharp.Net.Http; - -//using Newtonsoft.Json; -//using Newtonsoft.Json.Linq; - -//using PepperDash.Essentials.Core; -//using PepperDash.Essentials.Core.Http; -//using PepperDash.Core; - -//namespace PepperDash.Essentials -//{ -// public class EssentialsHttpApiHandler -// { -// string ConfigPath; -// string PresetsPathPrefix; -// EssentialsHttpServer Server; - -// /// -// /// -// /// -// /// HTTP server to attach to -// /// The full path to configuration file -// /// The folder prefix for the presets path, eq "\HTML\presets\" -// public EssentialsHttpApiHandler(EssentialsHttpServer server, string configPath, string presetsPathPrefix) -// { -// if (server == null) throw new ArgumentNullException("server"); -// Server = server; -// ConfigPath = configPath; -// PresetsPathPrefix = presetsPathPrefix; -// server.ApiRequest += Server_ApiRequest; -// } - - -// void Server_ApiRequest(object sender, Crestron.SimplSharp.Net.Http.OnHttpRequestArgs args) -// { -// try -// { -// var path = args.Request.Path.ToLower(); - -// if (path == "/api/config") -// HandleApiConfig(args); -// else if (path.StartsWith("/api/presetslist/")) -// HandleApiPresetsList(args); -// else if (path == "/api/presetslists") -// HandleApiGetPresetsLists(args.Request, args.Response); -// else -// { -// args.Response.Code = 404; -// return; -// } -// args.Response.Header.SetHeaderValue("Access-Control-Allow-Origin", "*"); -// args.Response.Header.SetHeaderValue("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS"); -// } -// catch (Exception e) -// { -// Debug.Console(1, "Uncaught HTTP server error: \n{0}", e); -// args.Response.Code = 500; -// } -// } - -// /// -// /// GET will return the running configuration. POST will attempt to take in a new config -// /// and restart the program. -// /// -// void HandleApiConfig(OnHttpRequestArgs args) -// { -// var request = args.Request; -// if (request.Header.RequestType == "GET") -// { -// if (File.Exists(ConfigPath)) -// { -// Debug.Console(2, "Sending config:{0}", ConfigPath); -// args.Response.Header.ContentType = EssentialsHttpServer.GetContentType(new FileInfo(ConfigPath).Extension); -// args.Response.ContentStream = new FileStream(ConfigPath, FileMode.Open, FileAccess.Read); -// } -// } -// else if (request.Header.RequestType == "POST") -// { -// Debug.Console(2, "Post type: '{0}'", request.Header.ContentType); - -// // Make sure we're receiving at least good json -// Debug.Console(1, "Receving new config"); -// if (GetContentStringJson(args) == null) -// return; - -// //---------------------------- try to move these into common method -// // Move current file aside -// var bakPath = ConfigPath + ".bak"; -// if (File.Exists(bakPath)) -// File.Delete(bakPath); -// File.Move(ConfigPath, bakPath); - -// // Write the file -// using (FileStream fs = File.Open(ConfigPath, FileMode.OpenOrCreate)) -// using (StreamWriter sw = new StreamWriter(fs)) -// { -// try -// { -// sw.Write(args.Request.ContentString); -// } -// catch (Exception e) -// { -// string err = string.Format("Error writing received config file:\r{0}", e); -// CrestronConsole.PrintLine(err); -// ErrorLog.Warn(err); -// // Put file back -// File.Move(ConfigPath + ".bak", ConfigPath); -// args.Response.Code = 500; -// return; -// } -// } - -// // If client says "yeah, restart" and has a good token -// // Restart program -// string consoleResponse = null; -// var restart = CrestronConsole.SendControlSystemCommand("progreset -p:" + -// InitialParametersClass.ApplicationNumber, ref consoleResponse); -// if (!restart) Debug.Console(0, "CAN'T DO THAT YO: {0}", consoleResponse); -// } -// } - -// void HandleApiPresetsList(OnHttpRequestArgs args) -// { -// var listPath = PresetsPathPrefix + args.Request.Path.Remove(0, 17); -// Debug.Console(2, "Checking for preset list '{0}'", listPath); - -// if (args.Request.Header.RequestType == "GET") -// { -// if (File.Exists(listPath)) -// { -// Debug.Console(2, "Sending presets file:{0}", listPath); -// args.Response.Header.ContentType = EssentialsHttpServer.GetContentType(new FileInfo(listPath).Extension); -// args.Response.ContentStream = new FileStream(listPath, FileMode.Open, FileAccess.Read); -// } -// } -// else if (args.Request.Header.RequestType == "POST") -// { -// // Make sure we're receiving at least good json -// Debug.Console(1, "Receving new presets"); -// if (GetContentStringJson(args) == null) -// return; - -// //---------------------------- try to move these into common method -// // Move current file aside -// var bakPath = listPath + ".new"; -// Debug.Console(2, "Moving presets file to {0}", bakPath); -// if(File.Exists(bakPath)) -// File.Delete(bakPath); -// File.Move(listPath, bakPath); - -// Debug.Console(2, "Writing new file"); -// // Write the file -// using (FileStream fs = File.OpenWrite(listPath)) -// using (StreamWriter sw = new StreamWriter(fs)) -// { -// try -// { -// Debug.Console(2, "Writing {1}, {0} bytes", args.Request.ContentString.Length, listPath); -// sw.Write(args.Request.ContentString); -// } -// catch (Exception e) -// { -// string err = string.Format("Error writing received presets file:\r{0}", e); -// CrestronConsole.PrintLine(err); -// ErrorLog.Warn(err); -// // Put file back -// File.Move(listPath + ".bak", listPath); -// args.Response.Code = 500; -// return; -// } -// } -// } -// } - - -// void HandleApiGetPresetsLists(HttpServerRequest request, HttpServerResponse response) -// { -// if (request.Header.RequestType != "GET") -// { -// response.Code = 404; // This should be a 405 with an allow header -// return; -// } - -// if (Directory.Exists(PresetsPathPrefix)) -// { -// //CrestronConsole.PrintLine("Parsing presets directory"); -// List files = Directory.GetFiles(PresetsPathPrefix, "*.json") -// .ToList().Select(f => Path.GetFileName(f)).ToList(); -// if (files.Count > 0) -// files.Sort(); -// var json = JsonConvert.SerializeObject(files); -// response.Header.ContentType = "application/json"; -// response.ContentString = json; -// } - -// // //CrestronConsole.PrintLine("Found {0} files", files.Count); -// // JObject jo = new JObject(); -// // JArray ja = new JArray(); - -// // foreach (var filename in files) -// // { -// // try -// // { -// // using (StreamReader sr = new StreamReader(filename)) -// // { -// // JObject tempJo = JObject.Parse(sr.ReadToEnd()); -// // if (tempJo.Value("content").Equals("presetsList")) -// // { -// // var jItem = new JObject(); // make a new object -// // jItem.Add("Name", tempJo["name"]); -// // jItem.Add("File", filename); -// // jItem.Add("Url", Uri.EscapeUriString(new Uri( -// // filename.Replace("\\html", "") -// // .Replace("\\HTML", "") -// // .Replace('\\', '/'), UriKind.Relative).ToString())); -// // ja.Add(jItem); // add to array -// // } -// // else -// // CrestronConsole.PrintLine("Cannot use presets file '{0}'", filename); -// // } -// // } -// // catch -// // { -// // // ignore failures - maybe delete them -// // CrestronConsole.PrintLine("Unable to read presets file '{0}'", filename); -// // } -// // } -// // jo.Add("PresetChannelLists", ja); -// // //CrestronConsole.PrintLine(jo.ToString()); -// // response.Header.ContentType = "application/json"; -// // response.ContentString = jo.ToString(); -// //} -// //else -// // CrestronConsole.PrintLine("No presets files in directory"); -// } - -// /// -// /// Simply does what it says -// /// -// JObject GetContentStringJson(OnHttpRequestArgs args) -// { -// //var content = args.Request.ContentString; -// //Debug.Console(1, "{0}", content); - -// try -// { -// // just see if it parses properly -// return JObject.Parse(args.Request.ContentString); -// } -// catch (Exception e) -// { -// string err = string.Format("JSON Error reading config file:\r{0}", e); -// CrestronConsole.PrintLine(err); -// ErrorLog.Warn(err); -// args.Response.Code = 400; // Bad request -// return null; -// } -// } -// } -//} \ No newline at end of file diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index dcd5b0c9..b2bd2802 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -131,6 +131,7 @@ + @@ -163,6 +164,7 @@ + @@ -172,7 +174,7 @@ - + diff --git a/PepperDashEssentials/PluginLoading/PluginLoading.cs b/PepperDashEssentials/PluginLoading/PluginLoading.cs new file mode 100644 index 00000000..032bea2e --- /dev/null +++ b/PepperDashEssentials/PluginLoading/PluginLoading.cs @@ -0,0 +1,444 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials +{ + /// + /// Deals with loading plugins at runtime + /// + public static class PluginLoader + { + /// + /// The complete list of loaded assemblies. Includes Essentials Framework assemblies and plugins + /// + public static List LoadedAssemblies { get; private set; } + + /// + /// The list of assemblies loaded from the plugins folder + /// + static List LoadedPluginFolderAssemblies; + + /// + /// The directory to look in for .cplz plugin packages + /// + static string _pluginDirectory = Global.FilePathPrefix + "plugins"; + + /// + /// The directory where plugins will be moved to and loaded from + /// + static string _loadedPluginsDirectoryPath = _pluginDirectory + Global.DirectorySeparator + "loadedAssemblies"; + + // The temp directory where .cplz archives will be unzipped to + static string _tempDirectory = _pluginDirectory + Global.DirectorySeparator + "temp"; + + + static PluginLoader() + { + LoadedAssemblies = new List(); + LoadedPluginFolderAssemblies = new List(); + } + + /// + /// Retrieves all the loaded assemblies from the program directory + /// + public static void AddProgramAssemblies() + { + Debug.Console(2, "Getting Assemblies loaded with Essentials"); + // Get the loaded assembly filenames + var appDi = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix); + var assemblyFiles = appDi.GetFiles("*.dll"); + + Debug.Console(2, "Found {0} Assemblies", assemblyFiles.Length); + + foreach (var fi in assemblyFiles) + { + string version = string.Empty; + Assembly assembly = null; + + switch (fi.Name) + { + case ("PepperDashEssentials.dll"): + { + version = Global.AssemblyVersion; + assembly = Assembly.GetExecutingAssembly(); + break; + } + case ("PepperDash_Core.dll"): + { + version = PepperDash.Core.Debug.PepperDashCoreVersion; + break; + } + } + + LoadedAssemblies.Add(new LoadedAssembly(fi.Name, version, assembly)); + } + + if (Debug.Level > 1) + { + Debug.Console(2, "Loaded Assemblies:"); + + foreach (var assembly in LoadedAssemblies) + { + Debug.Console(2, "Assembly: {0}", assembly.Name); + } + } + } + + /// + /// Loads an assembly via Reflection and adds it to the list of loaded assemblies + /// + /// + static LoadedAssembly LoadAssembly(string filePath) + { + Debug.Console(2, "Attempting to load {0}", filePath); + var assembly = Assembly.LoadFrom(filePath); + if (assembly != null) + { + var assyVersion = GetAssemblyVersion(assembly); + + var loadedAssembly = new LoadedAssembly(assembly.GetName().Name, assyVersion, assembly); + LoadedAssemblies.Add(loadedAssembly); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded assembly '{0}', version {1}", loadedAssembly.Name, loadedAssembly.Version); + return loadedAssembly; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to load assembly: '{0}'", filePath); + } + + return null; + + } + + /// + /// Attempts to get the assembly informational version and if not possible gets the version + /// + /// + /// + static string GetAssemblyVersion(Assembly assembly) + { + var ver = assembly.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false); + if (ver != null && ver.Length > 0) + { + // Get the AssemblyInformationalVersion + AssemblyInformationalVersionAttribute verAttribute = ver[0] as AssemblyInformationalVersionAttribute; + return verAttribute.InformationalVersion; + } + else + { + // Get the AssemblyVersion + var version = assembly.GetName().Version; + var verStr = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build, version.Revision); + return verStr; + } + } + + /// + /// Checks if the filename matches an already loaded assembly file's name + /// + /// + /// True if file already matches loaded assembly file. + public static bool CheckIfAssemblyLoaded(string name) + { + Debug.Console(2, "Checking if assembly: {0} is loaded...", name); + var loadedAssembly = LoadedAssemblies.FirstOrDefault(s => s.Name.Equals(name)); + + if (loadedAssembly != null) + { + Debug.Console(2, "Assembly already loaded."); + return true; + } + else + { + Debug.Console(2, "Assembly not loaded."); + return false; + } + } + + /// + /// Used by console command to report the currently loaded assemblies and versions + /// + /// + public static void ReportAssemblyVersions(string command) + { + Debug.Console(0, "Loaded Assemblies:"); + foreach (var assembly in LoadedAssemblies) + { + Debug.Console(0, "{0} Version: {1}", assembly.Name, assembly.Version); + } + } + + /// + /// Moves any .dll assemblies not already loaded from the plugins folder to loadedPlugins folder + /// + static void MoveDllAssemblies() + { + Debug.Console(0, "Looking for .dll assemblies from plugins folder..."); + + var pluginDi = new DirectoryInfo(_pluginDirectory); + var pluginFiles = pluginDi.GetFiles("*.dll"); + + if (pluginFiles.Length > 0) + { + if (!Directory.Exists(_loadedPluginsDirectoryPath)) + { + Directory.CreateDirectory(_loadedPluginsDirectoryPath); + } + } + + foreach (var pluginFile in pluginFiles) + { + try + { + Debug.Console(0, "Found .dll: {0}", pluginFile.Name); + + if (!CheckIfAssemblyLoaded(pluginFile.Name)) + { + string filePath = string.Empty; + + filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + pluginFile.Name; + + // Check if there is a previous file in the loadedPlugins directory and delete + if (File.Exists(filePath)) + { + Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath); + File.Delete(filePath); + } + + // Move the file + File.Move(pluginFile.FullName, filePath); + Debug.Console(2, "Moved {0} to {1}", pluginFile.FullName, filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", pluginFile.FullName); + } + } + catch (Exception e) + { + Debug.Console(2, "Error with plugin file {0} . Exception: {1}", pluginFile.FullName, e); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + + Debug.Console(0, "Done with .dll assemblies"); + } + + /// + /// Unzips each .cplz archive into the temp directory and moves any unloaded files into loadedPlugins + /// + static void UnzipAndMoveCplzArchives() + { + Debug.Console(0, "Looking for .cplz archives from plugins folder..."); + var di = new DirectoryInfo(_pluginDirectory); + var zFiles = di.GetFiles("*.cplz"); + + if (zFiles.Length > 0) + { + if (!Directory.Exists(_loadedPluginsDirectoryPath)) + { + Directory.CreateDirectory(_loadedPluginsDirectoryPath); + } + } + + foreach (var zfi in zFiles) + { + Directory.CreateDirectory(_tempDirectory); + var tempDi = new DirectoryInfo(_tempDirectory); + + Debug.Console(0, "Found cplz: {0}. Unzipping into temp plugins directory", zfi.Name); + var result = CrestronZIP.Unzip(zfi.FullName, tempDi.FullName); + Debug.Console(0, "UnZip Result: {0}", result.ToString()); + + var tempFiles = tempDi.GetFiles("*.dll"); + foreach (var tempFile in tempFiles) + { + try + { + if (!CheckIfAssemblyLoaded(tempFile.Name)) + { + string filePath = string.Empty; + + filePath = _loadedPluginsDirectoryPath + Global.DirectorySeparator + tempFile.Name; + + // Check if there is a previous file in the loadedPlugins directory and delete + if (File.Exists(filePath)) + { + Debug.Console(0, "Found existing file in loadedPlugins: {0} Deleting and moving new file to replace it", filePath); + File.Delete(filePath); + } + + // Move the file + File.Move(tempFile.FullName, filePath); + Debug.Console(2, "Moved {0} to {1}", tempFile.FullName, filePath); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Skipping assembly: {0}. There is already an assembly with that name loaded.", tempFile.FullName); + } + } + catch (Exception e) + { + Debug.Console(2, "Assembly {0} is not a custom assembly. Exception: {1}", tempFile.FullName, e); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + + // Delete the .cplz and the temp directory + Directory.Delete(_tempDirectory, true); + zfi.Delete(); + } + + Debug.Console(0, "Done with .cplz archives"); + } + + /// + /// Attempts to load the assemblies from the loadedPlugins folder + /// + static void LoadPluginAssemblies() + { + Debug.Console(0, "Loading assemblies from loadedPlugins folder..."); + var pluginDi = new DirectoryInfo(_loadedPluginsDirectoryPath); + var pluginFiles = pluginDi.GetFiles("*.dll"); + + Debug.Console(2, "Found {0} plugin assemblies to load", pluginFiles.Length); + + foreach (var pluginFile in pluginFiles) + { + var loadedAssembly = LoadAssembly(pluginFile.FullName); + + LoadedPluginFolderAssemblies.Add(loadedAssembly); + } + + Debug.Console(0, "All Plugins Loaded."); + } + + /// + /// Iterate the loaded assemblies and try to call the LoadPlugin method + /// + static void LoadCustomPluginTypes() + { + Debug.Console(0, "Loading Custom Plugin Types..."); + foreach (var loadedAssembly in LoadedPluginFolderAssemblies) + { + // iteratate this assembly's classes, looking for "LoadPlugin()" methods + try + { + var assy = loadedAssembly.Assembly; + var types = assy.GetTypes(); + foreach (var type in types) + { + try + { + var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); + var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); + if (loadPlugin != null) + { + Debug.Console(2, "LoadPlugin method found in {0}", type.Name); + + var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static); + + var minimumVersion = fields.FirstOrDefault(p => p.Name.Equals("MinimumEssentialsFrameworkVersion")); + if (minimumVersion != null) + { + Debug.Console(2, "MinimumEssentialsFrameworkVersion found"); + + var minimumVersionString = minimumVersion.GetValue(null) as string; + + if (!string.IsNullOrEmpty(minimumVersionString)) + { + var passed = Global.IsRunningMinimumVersionOrHigher(minimumVersionString); + + if (!passed) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", minimumVersionString); + continue; + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Passed plugin passed dependency check (required version {0})", minimumVersionString); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion found but not set. Loading plugin, but your mileage may vary."); + } + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "MinimumEssentialsFrameworkVersion not found. Loading plugin, but your mileage may vary."); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding plugin: {0}", loadedAssembly.Name); + loadPlugin.Invoke(null, null); + } + } + catch (Exception e) + { + Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly. Exception: {1}", loadedAssembly.Name, e); + continue; + } + + } + } + catch (Exception e) + { + Debug.Console(2, "Error Loading Assembly: {0} Exception: (1) ", loadedAssembly.Name, e); + continue; + } + } + // plugin dll will be loaded. Any classes in plugin should have a static constructor + // that registers that class with the Core.DeviceFactory + Debug.Console(0, "Done Loading Custom Plugin Types."); + } + + /// + /// Loads plugins + /// + public static void LoadPlugins() + { + if (Directory.Exists(_pluginDirectory)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for plugins"); + + // Deal with any .dll files + MoveDllAssemblies(); + + // Deal with any .cplz files + UnzipAndMoveCplzArchives(); + + // Load the assemblies from the loadedPlugins folder into the AppDomain + LoadPluginAssemblies(); + + // Load the types from any custom plugin assemblies + LoadCustomPluginTypes(); + } + } + + } + + /// + /// Represents an assembly loaded at runtime and it's associated metadata + /// + public class LoadedAssembly + { + public string Name { get; private set; } + public string Version { get; private set; } + public Assembly Assembly { get; private set; } + + public LoadedAssembly(string name, string version, Assembly assembly) + { + Name = name; + Version = version; + Assembly = assembly; + } + } +} \ No newline at end of file diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.DM.dll b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.DM.dll deleted file mode 100644 index 7ecd0053..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.DM.dll and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.DeviceSupport.dll b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.DeviceSupport.dll deleted file mode 100644 index c224b067..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.DeviceSupport.dll and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.EthernetCommunications.dll b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.EthernetCommunications.dll deleted file mode 100644 index 802bed98..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.EthernetCommunications.dll and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.UI.dll b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.UI.dll deleted file mode 100644 index d098a7e0..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/Crestron.SimplSharpPro.UI.dll and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.config b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.config deleted file mode 100644 index 2ae09e62..00000000 --- a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.config +++ /dev/null @@ -1,16 +0,0 @@ - - - PepperDashEssentials - PepperDashEssentialsBase - PepperDashEssentialsBase - 1.009.0029 - SIMPL# Plugin - 5 - 5 - - - - 1/8/2016 3:03:22 PM - 1.0.0.27100 - - \ No newline at end of file diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.cplz b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.cplz deleted file mode 100644 index 95fbc0f6..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.cplz and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.dll b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.dll deleted file mode 100644 index 37d0e907..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/PepperDashEssentialsBase.dll and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/SimplSharpData.dat b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/SimplSharpData.dat deleted file mode 100644 index 816bfe12..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/SimplSharpData.dat and /dev/null differ diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/manifest.info b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/manifest.info deleted file mode 100644 index ab17c183..00000000 --- a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/manifest.info +++ /dev/null @@ -1,18 +0,0 @@ -MainAssembly=PepperDashEssentialsBase.dll:5d68a993ab03b4b88d0f95478188a439 -MainAssemblyMinFirmwareVersion=1.009.0029 -ü -DependencySource=Crestron.SimplSharpPro.DeviceSupport.dll:caae4b4259aaf619059f0ae34473bfd2 -DependencyPath=PepperDashEssentialsBase.cplz:Crestron.SimplSharpPro.DeviceSupport.dll -DependencyMainAssembly=Crestron.SimplSharpPro.DeviceSupport.dll:caae4b4259aaf619059f0ae34473bfd2 -ü -DependencySource=Crestron.SimplSharpPro.DM.dll:bdf5acfa80cc3bb87f21deb891128b1d -DependencyPath=PepperDashEssentialsBase.cplz:Crestron.SimplSharpPro.DM.dll -DependencyMainAssembly=Crestron.SimplSharpPro.DM.dll:bdf5acfa80cc3bb87f21deb891128b1d -ü -DependencySource=Crestron.SimplSharpPro.EthernetCommunications.dll:36e663497195140ee6f1b4ebc53f5ea7 -DependencyPath=PepperDashEssentialsBase.cplz:Crestron.SimplSharpPro.EthernetCommunications.dll -DependencyMainAssembly=Crestron.SimplSharpPro.EthernetCommunications.dll:36e663497195140ee6f1b4ebc53f5ea7 -ü -DependencySource=Crestron.SimplSharpPro.UI.dll:089312a0cb0b4537072d4eb234e71e0e -DependencyPath=PepperDashEssentialsBase.cplz:Crestron.SimplSharpPro.UI.dll -DependencyMainAssembly=Crestron.SimplSharpPro.UI.dll:089312a0cb0b4537072d4eb234e71e0e diff --git a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/manifest.ser b/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/manifest.ser deleted file mode 100644 index 13cd9db7..00000000 Binary files a/PepperDashEssentials/References/PepperDashEssentialsBase.cplz/manifest.ser and /dev/null differ diff --git a/devjson commands.json b/devjson commands.json index e7a8a884..62e675d1 100644 --- a/devjson commands.json +++ b/devjson commands.json @@ -40,4 +40,5 @@ devjson:1 {"deviceKey":"commBridge", "methodName":"ExecuteJoinAction", "params": devjson:2 {"deviceKey":"display01Comm-com", "methodName":"SendText", "params": [ "I'M GETTING TIRED OF THIS" ]} -devjson:10 {"deviceKey":"dmLink-ssh", "methodName":"Connect", "params": []} \ No newline at end of file +devjson:10 {"deviceKey":"dmLink-ssh", "methodName":"Connect", "params": []} + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs index 0a288944..b3fc7d89 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Config/Essentials/ConfigReader.cs @@ -64,16 +64,23 @@ namespace PepperDash.Essentials.Core.Config if (configFiles != null) { + Debug.Console(2, "{0} config files found matching pattern", configFiles.Length); + if (configFiles.Length > 1) { Debug.Console(0, Debug.ErrorLogLevel.Error, "****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****"); return false; } - else + else if (configFiles.Length == 1) { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath); } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found."); + return false; + } } else { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceFeedbackExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceFeedbackExtensions.cs new file mode 100644 index 00000000..1ef59b0f --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceFeedbackExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + public static class DeviceFeedbackExtensions + { + /// + /// Attempts to get and return a feedback property from a device by name. + /// If unsuccessful, returns null. + /// + /// + /// + /// + public static Feedback GetFeedbackProperty(this Device device, string propertyName) + { + var feedback = DeviceJsonApi.GetPropertyByName(device.Key, propertyName) as Feedback; + + if (feedback != null) + { + return feedback; + } + + return null; + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs index 32d53388..c7bc7c68 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceJsonApi.cs @@ -59,7 +59,7 @@ namespace PepperDash.Essentials.Core } /// - /// + /// Gets the properties on a device /// /// /// @@ -75,8 +75,34 @@ namespace PepperDash.Essentials.Core return JsonConvert.SerializeObject(props, Formatting.Indented); } + /// + /// Gets a property from a device path by name + /// + /// + /// + /// + public static object GetPropertyByName(string deviceObjectPath, string propertyName) + { + var obj = FindObjectOnPath(deviceObjectPath); + if(obj == null) + return "{ \"error\":\"No Device\"}"; + + CType t = obj.GetType(); + + var prop = t.GetProperty(propertyName); + if (prop != null) + { + return prop; + } + else + { + Debug.Console(1, "Unable to find Property: {0} on Device with path: {1}", propertyName, deviceObjectPath); + return null; + } + } + /// - /// + /// Gets the methods on a device /// /// /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs index 8bc89bd4..c07bc010 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs @@ -9,6 +9,7 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.CrestronIO; +using PepperDash.Essentials.Core.Touchpanels; namespace PepperDash.Essentials.Core { @@ -47,13 +48,21 @@ namespace PepperDash.Essentials.Core var typeName = dc.Type.ToLower(); - // Check "core" types first + + // Check for types that have been added by plugin dlls. + if (FactoryMethods.ContainsKey(typeName)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type); + return FactoryMethods[typeName](dc); + } + + // Check "core" types if (typeName == "genericcomm") { Debug.Console(1, "Factory Attempting to create new Generic Comm Device"); return new GenericComm(dc); } - else if (typeName == "ceniodigin104") + if (typeName == "ceniodigin104") { var control = CommFactory.GetControlPropertiesConfig(dc); var ipid = control.IpIdInt; @@ -75,13 +84,6 @@ namespace PepperDash.Essentials.Core return new C2nRthsController(key, name, new C2nRths(cresnetId, Global.ControlSystem)); } - // then check for types that have been added by plugin dlls. - if (FactoryMethods.ContainsKey(typeName)) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type); - return FactoryMethods[typeName](dc); - } - return null; } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs index 9fb4c1e1..f46b4767 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/BoolFeedback.cs @@ -32,18 +32,36 @@ namespace PepperDash.Essentials.Core List LinkedInputSigs = new List(); List LinkedComplementInputSigs = new List(); + List LinkedCrestronFeedbacks = new List(); + + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Delegate to invoke when this feedback needs to be updated public BoolFeedback(Func valueFunc) : this(null, valueFunc) { } + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Key to find this Feedback + /// Delegate to invoke when this feedback needs to be updated public BoolFeedback(string key, Func valueFunc) : base(key) { ValueFunc = valueFunc; } - public override void FireUpdate() { bool newValue = InTestMode ? TestValue : ValueFunc.Invoke(); @@ -56,28 +74,63 @@ namespace PepperDash.Essentials.Core } } + /// + /// Links an input sig + /// + /// public void LinkInputSig(BoolInputSig sig) { LinkedInputSigs.Add(sig); UpdateSig(sig); } + /// + /// Unlinks an inputs sig + /// + /// public void UnlinkInputSig(BoolInputSig sig) { LinkedInputSigs.Remove(sig); } + /// + /// Links an input sig to the complement value + /// + /// public void LinkComplementInputSig(BoolInputSig sig) { LinkedComplementInputSigs.Add(sig); UpdateComplementSig(sig); } + /// + /// Unlinks an input sig to the complement value + /// + /// public void UnlinkComplementInputSig(BoolInputSig sig) { LinkedComplementInputSigs.Remove(sig); } + /// + /// Links a Crestron Feedback object + /// + /// + public void LinkCrestronFeedback(Crestron.SimplSharpPro.DeviceSupport.Feedback feedback) + { + LinkedCrestronFeedbacks.Add(feedback); + UpdateCrestronFeedback(feedback); + } + + /// + /// + /// + /// + public void UnlinkCrestronFeedback(Crestron.SimplSharpPro.DeviceSupport.Feedback feedback) + { + LinkedCrestronFeedbacks.Remove(feedback); + } + public override string ToString() { return (InTestMode ? "TEST -- " : "") + BoolValue.ToString(); @@ -103,6 +156,11 @@ namespace PepperDash.Essentials.Core { sig.BoolValue = !_BoolValue; } + + void UpdateCrestronFeedback(Crestron.SimplSharpPro.DeviceSupport.Feedback feedback) + { + feedback.State = _BoolValue; + } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs index 4a278148..25390c2c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/IntFeedback.cs @@ -23,11 +23,28 @@ namespace PepperDash.Essentials.Core Func ValueFunc; List LinkedInputSigs = new List(); + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Delegate to invoke when this feedback needs to be updated public IntFeedback(Func valueFunc) : this(null, valueFunc) { } + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Key to find this Feedback + /// Delegate to invoke when this feedback needs to be updated public IntFeedback(string key, Func valueFunc) : base(key) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs index b02c02f0..56251a2e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Feedbacks/StringFeedback.cs @@ -7,6 +7,7 @@ using Crestron.SimplSharpPro; namespace PepperDash.Essentials.Core { + public class StringFeedback : Feedback { public override string StringValue { get { return _StringValue; } } // ValueFunc.Invoke(); } } @@ -18,16 +19,33 @@ namespace PepperDash.Essentials.Core public string TestValue { get; private set; } /// - /// Evalutated on FireUpdate + /// Evaluated on FireUpdate /// public Func ValueFunc { get; private set; } List LinkedInputSigs = new List(); + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Delegate to invoke when this feedback needs to be updated public StringFeedback(Func valueFunc) : this(null, valueFunc) { } + /// + /// Creates the feedback with the Func as described. + /// + /// + /// While the linked sig value will be updated with the current value stored when it is linked to a EISC Bridge, + /// it will NOT reflect an actual value from a device until has been called + /// + /// Key to find this Feedback + /// Delegate to invoke when this feedback needs to be updated public StringFeedback(string key, Func valueFunc) : base(key) { diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index e8422f95..1134f3e2 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -439,7 +439,7 @@ namespace PepperDash.Essentials.Core.Fusion void GetTouchpanelInfo() { - // TODO Get IP and Project Name from TP + // TODO: Get IP and Project Name from TP } protected void FusionRoom_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs index 4ef68066..de533ebb 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Global/Global.cs @@ -98,7 +98,7 @@ namespace PepperDash.Essentials.Core { Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion); - var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*)$"); + var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*"); var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value); var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value); @@ -107,7 +107,7 @@ namespace PepperDash.Essentials.Core // Check for beta build version if (runtimeVersionMajor == 0) { - Debug.Console(2, "Running Beta Build. Bypassing Dependency Check."); + Debug.Console(2, "Running Local Build. Bypassing Dependency Check."); return true; } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs index 4cc245e0..495a4a58 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs @@ -1,13 +1,8 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharpPro.Diagnostics; - using PepperDash.Core; -using PepperDash.Essentials.Core; - using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -19,18 +14,32 @@ namespace PepperDash.Essentials.Core.Monitoring /// public class SystemMonitorController : Device { + private const long UptimePollTime = 300000; + private CTimer _uptimePollTimer; + + private string _uptime; + private string _lastStart; + public event EventHandler SystemMonitorPropertiesChanged; public Dictionary ProgramStatusFeedbackCollection; + public Dictionary EthernetStatusFeedbackCollection; - public IntFeedback TimeZoneFeedback { get; set; } - public StringFeedback TimeZoneTextFeedback { get; set; } + public IntFeedback TimeZoneFeedback { get; protected set; } + public StringFeedback TimeZoneTextFeedback { get; protected set; } + + public StringFeedback IoControllerVersionFeedback { get; protected set; } + public StringFeedback SnmpVersionFeedback { get; protected set; } + public StringFeedback BaCnetAppVersionFeedback { get; protected set; } + public StringFeedback ControllerVersionFeedback { get; protected set; } + + //new feedbacks. Issue #50 + public StringFeedback SerialNumberFeedback { get; protected set; } + public StringFeedback ModelFeedback { get; set; } + + public StringFeedback UptimeFeedback { get; set; } + public StringFeedback LastStartFeedback { get; set; } - public StringFeedback IOControllerVersionFeedback { get; set; } - public StringFeedback SnmpVersionFeedback { get; set; } - public StringFeedback BACnetAppVersionFeedback { get; set; } - public StringFeedback ControllerVersionFeedback { get; set; } - public SystemMonitorController(string key) : base(key) { @@ -38,21 +47,18 @@ namespace PepperDash.Essentials.Core.Monitoring SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; - //CrestronConsole.AddNewConsoleCommand(RefreshSystemMonitorData, "RefreshSystemMonitor", "Refreshes System Monitor Feedbacks", ConsoleAccessLevelEnum.AccessOperator); + TimeZoneFeedback = new IntFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneNumber); + TimeZoneTextFeedback = new StringFeedback(() => SystemMonitor.TimeZoneInformation.TimeZoneName); - TimeZoneFeedback = new IntFeedback(new Func( () => SystemMonitor.TimeZoneInformation.TimeZoneNumber)); - TimeZoneTextFeedback = new StringFeedback(new Func( () => SystemMonitor.TimeZoneInformation.TimeZoneName)); + IoControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.IOPVersion); + SnmpVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.SNMPVersion); + BaCnetAppVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.BACNetVersion); + ControllerVersionFeedback = new StringFeedback(() => SystemMonitor.VersionInformation.ControlSystemVersion); - IOControllerVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.IOPVersion)); - SnmpVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.SNMPVersion)); - BACnetAppVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.BACNetVersion)); - ControllerVersionFeedback = new StringFeedback(new Func( () => SystemMonitor.VersionInformation.ControlSystemVersion)); - - //var status = string.Format("System Monitor Status: \r TimeZone: {0}\rTimeZoneText: {1}\rIOControllerVersion: {2}\rSnmpAppVersionFeedback: {3}\rBACnetAppVersionFeedback: {4}\rControllerVersionFeedback: {5}", - // SystemMonitor.TimeZoneInformation.TimeZoneNumber, SystemMonitor.TimeZoneInformation.TimeZoneName, SystemMonitor.VersionInformation.IOPVersion, SystemMonitor.VersionInformation.SNMPVersion, - // SystemMonitor.VersionInformation.BACNetVersion, SystemMonitor.VersionInformation.ControlSystemVersion); - - //Debug.Console(1, this, status); + SerialNumberFeedback = new StringFeedback(() => CrestronEnvironment.SystemInfo.SerialNumber); + ModelFeedback = new StringFeedback(() => InitialParametersClass.ControllerPromptName); + UptimeFeedback = new StringFeedback(() => _uptime); + LastStartFeedback = new StringFeedback(()=> _lastStart); ProgramStatusFeedbackCollection = new Dictionary(); @@ -62,43 +68,132 @@ namespace PepperDash.Essentials.Core.Monitoring ProgramStatusFeedbackCollection.Add(prog.Number, program); } - SystemMonitor.ProgramChange += new ProgramStateChangeEventHandler(SystemMonitor_ProgramChange); - SystemMonitor.TimeZoneInformation.TimeZoneChange += new TimeZoneChangeEventHandler(TimeZoneInformation_TimeZoneChange); + CreateEthernetStatusFeedbacks(); + UpdateEthernetStatusFeeedbacks(); + + _uptimePollTimer = new CTimer(PollUptime,null,0, UptimePollTime); + + SystemMonitor.ProgramChange += SystemMonitor_ProgramChange; + SystemMonitor.TimeZoneInformation.TimeZoneChange += TimeZoneInformation_TimeZoneChange; + CrestronEnvironment.EthernetEventHandler += CrestronEnvironmentOnEthernetEventHandler; + CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironmentOnProgramStatusEventHandler; + } + + private void CrestronEnvironmentOnProgramStatusEventHandler(eProgramStatusEventType programEventType) + { + if (programEventType != eProgramStatusEventType.Stopping) return; + + _uptimePollTimer.Stop(); + _uptimePollTimer.Dispose(); + _uptimePollTimer = null; + } + + private void PollUptime(object obj) + { + var consoleResponse = string.Empty; + + CrestronConsole.SendControlSystemCommand("uptime", ref consoleResponse); + + ParseUptime(consoleResponse); + + UptimeFeedback.FireUpdate(); + LastStartFeedback.FireUpdate(); + } + + private void ParseUptime(string response) + { + var splitString = response.Trim().Split('\r', '\n'); + + var lastStartRaw = splitString[2]; + var lastStartIndex = lastStartRaw.IndexOf(':'); + + _lastStart = lastStartRaw.Substring(lastStartIndex + 1).Trim(); + + var uptimeRaw = splitString[0]; + + var forIndex = uptimeRaw.IndexOf("for", StringComparison.Ordinal); + + //4 => "for " to get what's on the right + _uptime = uptimeRaw.Substring(forIndex + 4); + } + + private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs) + { + if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return; + + foreach (var fb in EthernetStatusFeedbackCollection) + { + fb.Value.UpdateEthernetStatus(); + } + } + + private void CreateEthernetStatusFeedbacks() + { + EthernetStatusFeedbackCollection = new Dictionary(); + + Debug.Console(2, "Creating {0} EthernetStatusFeedbacks", InitialParametersClass.NumberOfEthernetInterfaces); + + for (short i = 0; i < InitialParametersClass.NumberOfEthernetInterfaces; i++) + { + Debug.Console(2, "Creating EthernetStatusFeedback for Interface {0}", i); + var ethernetInterface = new EthernetStatusFeedbacks(i); + EthernetStatusFeedbackCollection.Add(i, ethernetInterface); + } + } + + private void UpdateEthernetStatusFeeedbacks() + { + foreach (var iface in EthernetStatusFeedbackCollection) + { + iface.Value.CurrentIpAddressFeedback.FireUpdate(); + iface.Value.CurrentSubnetMaskFeedback.FireUpdate(); + iface.Value.CurrentDefaultGatewayFeedback.FireUpdate(); + iface.Value.StaticIpAddressFeedback.FireUpdate(); + iface.Value.StaticSubnetMaskFeedback.FireUpdate(); + iface.Value.StaticDefaultGatewayFeedback.FireUpdate(); + iface.Value.HostNameFeedback.FireUpdate(); + iface.Value.DnsServerFeedback.FireUpdate(); + iface.Value.DomainFeedback.FireUpdate(); + iface.Value.DhcpStatusFeedback.FireUpdate(); + iface.Value.MacAddressFeedback.FireUpdate(); + } } /// /// Gets data in separate thread /// - /// - void RefreshSystemMonitorData(string command) + private void RefreshSystemMonitorData() { // this takes a while, launch a new thread - CrestronInvoke.BeginInvoke((o) => - { - TimeZoneFeedback.FireUpdate(); - TimeZoneTextFeedback.FireUpdate(); - IOControllerVersionFeedback.FireUpdate(); - SnmpVersionFeedback.FireUpdate(); - BACnetAppVersionFeedback.FireUpdate(); - ControllerVersionFeedback.FireUpdate(); - - OnSystemMonitorPropertiesChanged(); - } - ); + CrestronInvoke.BeginInvoke(UpdateFeedback); } - void OnSystemMonitorPropertiesChanged() + private void UpdateFeedback(object o) + { + TimeZoneFeedback.FireUpdate(); + TimeZoneTextFeedback.FireUpdate(); + IoControllerVersionFeedback.FireUpdate(); + SnmpVersionFeedback.FireUpdate(); + BaCnetAppVersionFeedback.FireUpdate(); + ControllerVersionFeedback.FireUpdate(); + SerialNumberFeedback.FireUpdate(); + ModelFeedback.FireUpdate(); + + OnSystemMonitorPropertiesChanged(); + } + + private void OnSystemMonitorPropertiesChanged() { var handler = SystemMonitorPropertiesChanged; if (handler != null) { - handler(this, new EventArgs()); + handler(this, new EventArgs()); } } public override bool CustomActivate() { - RefreshSystemMonitorData(null); + RefreshSystemMonitorData(); return base.CustomActivate(); } @@ -114,46 +209,41 @@ namespace PepperDash.Essentials.Core.Monitoring /// /// /// - void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) + private void SystemMonitor_ProgramChange(Program sender, ProgramEventArgs args) { Debug.Console(2, this, "Program Change Detected for slot: {0}", sender.Number); Debug.Console(2, this, "Event Type: {0}", args.EventType); var program = ProgramStatusFeedbackCollection[sender.Number]; - if (args.EventType == eProgramChangeEventType.OperatingState) + switch (args.EventType) { - program.ProgramStartedFeedback.FireUpdate(); - program.ProgramStoppedFeedback.FireUpdate(); - - program.ProgramInfo.OperatingState = args.OperatingState; - - //program.GetProgramInfo(); - - if (args.OperatingState == eProgramOperatingState.Start) - program.GetProgramInfo(); - else - { - program.AggregatedProgramInfoFeedback.FireUpdate(); - program.OnProgramInfoChanged(); - } + case eProgramChangeEventType.OperatingState: + program.ProgramStartedFeedback.FireUpdate(); + program.ProgramStoppedFeedback.FireUpdate(); + program.ProgramInfo.OperatingState = args.OperatingState; + if (args.OperatingState == eProgramOperatingState.Start) + program.GetProgramInfo(); + else + { + program.AggregatedProgramInfoFeedback.FireUpdate(); + program.OnProgramInfoChanged(); + } + break; + case eProgramChangeEventType.RegistrationState: + program.ProgramRegisteredFeedback.FireUpdate(); + program.ProgramUnregisteredFeedback.FireUpdate(); + program.ProgramInfo.RegistrationState = args.RegistrationState; + program.GetProgramInfo(); + break; } - else if (args.EventType == eProgramChangeEventType.RegistrationState) - { - program.ProgramRegisteredFeedback.FireUpdate(); - program.ProgramUnregisteredFeedback.FireUpdate(); - - program.ProgramInfo.RegistrationState = args.RegistrationState; - - program.GetProgramInfo(); - } } /// /// Responds to time zone changes and updates the appropriate feedbacks /// /// - void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) + private void TimeZoneInformation_TimeZoneChange(TimeZoneEventArgs args) { Debug.Console(2, this, "Time Zone Change Detected."); TimeZoneFeedback.FireUpdate(); @@ -162,6 +252,121 @@ namespace PepperDash.Essentials.Core.Monitoring OnSystemMonitorPropertiesChanged(); } + public class EthernetStatusFeedbacks + { + public StringFeedback HostNameFeedback { get; protected set; } + public StringFeedback DnsServerFeedback { get; protected set; } + public StringFeedback DomainFeedback { get; protected set; } + public StringFeedback MacAddressFeedback { get; protected set; } + public StringFeedback DhcpStatusFeedback { get; protected set; } + + public StringFeedback CurrentIpAddressFeedback { get; protected set; } + public StringFeedback CurrentSubnetMaskFeedback { get; protected set; } + public StringFeedback CurrentDefaultGatewayFeedback { get; protected set; } + + public StringFeedback StaticIpAddressFeedback { get; protected set; } + public StringFeedback StaticSubnetMaskFeedback { get; protected set; } + public StringFeedback StaticDefaultGatewayFeedback { get; protected set; } + + public EthernetStatusFeedbacks(short adapterIndex) + { + Debug.Console(2, "Ethernet Information for interface {0}", adapterIndex); + Debug.Console(2, "Adapter Index: {1} Hostname: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Current Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static IP Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPADDRESS, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Subnet Mask: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_IPMASK, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Static Router: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_STATIC_ROUTER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DNS Servers: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} DHCP State: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} Domain Name: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex), adapterIndex); + Debug.Console(2, "Adapter Index: {1} MAC Address: {0}", CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex), adapterIndex); + HostNameFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, adapterIndex)); + + CurrentIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + CurrentDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + CurrentSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + StaticIpAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, adapterIndex)); + StaticDefaultGatewayFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_ROUTER, adapterIndex)); + StaticSubnetMaskFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_MASK, adapterIndex)); + DomainFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, adapterIndex)); + DnsServerFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DNS_SERVER, adapterIndex)); + MacAddressFeedback = + new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_MAC_ADDRESS, adapterIndex)); + + DhcpStatusFeedback = new StringFeedback( + () => + CrestronEthernetHelper.GetEthernetParameter( + CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_DHCP_STATE, adapterIndex)); + } + + public void UpdateEthernetStatus() + { + HostNameFeedback.FireUpdate(); + CurrentIpAddressFeedback.FireUpdate(); + CurrentSubnetMaskFeedback.FireUpdate(); + CurrentDefaultGatewayFeedback.FireUpdate(); + StaticIpAddressFeedback.FireUpdate(); + StaticSubnetMaskFeedback.FireUpdate(); + StaticDefaultGatewayFeedback.FireUpdate(); + DomainFeedback.FireUpdate(); + DnsServerFeedback.FireUpdate(); + MacAddressFeedback.FireUpdate(); + DhcpStatusFeedback.FireUpdate(); + } + } + public class ProgramStatusFeedbacks { @@ -192,17 +397,19 @@ namespace PepperDash.Essentials.Core.Monitoring ProgramInfo.OperatingState = Program.OperatingState; ProgramInfo.RegistrationState = Program.RegistrationState; - ProgramStartedFeedback = new BoolFeedback(new Func( () => Program.OperatingState == eProgramOperatingState.Start)); - ProgramStoppedFeedback = new BoolFeedback(new Func( () => Program.OperatingState == eProgramOperatingState.Stop)); - ProgramRegisteredFeedback = new BoolFeedback(new Func( () => Program.RegistrationState == eProgramRegistrationState.Register)); - ProgramUnregisteredFeedback = new BoolFeedback(new Func( () => Program.RegistrationState == eProgramRegistrationState.Unregister)); + ProgramStartedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Start); + ProgramStoppedFeedback = new BoolFeedback(() => Program.OperatingState == eProgramOperatingState.Stop); + ProgramRegisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Register); + ProgramUnregisteredFeedback = + new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister); - ProgramNameFeedback = new StringFeedback(new Func(() => ProgramInfo.ProgramFile)); - ProgramCompileTimeFeedback = new StringFeedback(new Func(() => ProgramInfo.CompileTime)); - CrestronDataBaseVersionFeedback = new StringFeedback(new Func(() => ProgramInfo.CrestronDB)); - EnvironmentVersionFeedback = new StringFeedback(new Func(() => ProgramInfo.Environment)); + ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile); + ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime); + CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb); + EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment); - AggregatedProgramInfoFeedback = new StringFeedback(new Func(() => JsonConvert.SerializeObject(ProgramInfo))); + AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo)); GetProgramInfo(); } @@ -212,74 +419,99 @@ namespace PepperDash.Essentials.Core.Monitoring /// public void GetProgramInfo() { - CrestronInvoke.BeginInvoke((o) => + CrestronInvoke.BeginInvoke(GetProgramInfo); + } + + private void GetProgramInfo(object o) + { + Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); + + string response = null; + + if (Program.RegistrationState == eProgramRegistrationState.Unregister || Program.OperatingState == eProgramOperatingState.Stop) { - Debug.Console(2, "Attempting to get program info for slot: {0}", Program.Number); + Debug.Console(2, "Program {0} not registered. Setting default values for program information.", + Program.Number); - string response = null; - - var success = CrestronConsole.SendControlSystemCommand(string.Format("progcomments:{0}", Program.Number), ref response); - - if (success) + ProgramInfo = new ProgramInfo(Program.Number) { - //Debug.Console(2, "Progcomments Response: \r{0}", response); + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; - if (!response.ToLower().Contains("bad or incomplete")) - { - // Shared properteis - ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); - ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); - ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); - ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); + return; + } + var success = CrestronConsole.SendControlSystemCommand( + string.Format("progcomments:{0}", Program.Number), ref response); + if (!success) + { + Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); + UpdateFeedbacks(); + return; + } - if (ProgramInfo.ProgramFile.Contains(".dll")) - { - // SSP Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); - ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); - ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); - ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", "\n"); - ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); - } - else if (ProgramInfo.ProgramFile.Contains(".smw")) - { - // SIMPL Windows Program - ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); - ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); - ProgramInfo.CrestronDB = ParseConsoleData(response, "CrestronDB", ": ", "\n"); - ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); - ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); + if (response.ToLower().Contains("bad or incomplete")) + { + Debug.Console(2, + "Program in slot {0} not running. Setting default ProgramInfo for slot: {0}", + Program.Number); - } - //Debug.Console(2, "ProgramInfo: \r{0}", JsonConvert.SerializeObject(ProgramInfo)); - } - else - { - Debug.Console(2, "Bad or incomplete console command response. Initializing ProgramInfo for slot: {0}", Program.Number); - - // Assume no valid program info. Constructing a new object will wipe all properties - ProgramInfo = new ProgramInfo(Program.Number); - - ProgramInfo.OperatingState = Program.OperatingState; - ProgramInfo.RegistrationState = Program.RegistrationState; - } - } - else + // Assume no valid program info. Constructing a new object will wipe all properties + ProgramInfo = new ProgramInfo(Program.Number) { - Debug.Console(2, "Progcomments Attempt Unsuccessful for slot: {0}", Program.Number); - } + OperatingState = Program.OperatingState, + RegistrationState = Program.RegistrationState + }; - ProgramNameFeedback.FireUpdate(); - ProgramCompileTimeFeedback.FireUpdate(); - CrestronDataBaseVersionFeedback.FireUpdate(); - EnvironmentVersionFeedback.FireUpdate(); + UpdateFeedbacks(); - AggregatedProgramInfoFeedback.FireUpdate(); + return; + } - OnProgramInfoChanged(); - }); + + // Shared properteis + ProgramInfo.ProgramFile = ParseConsoleData(response, "Program File", ": ", "\n"); + ProgramInfo.CompilerRevision = ParseConsoleData(response, "Compiler Rev", ": ", "\n"); + ProgramInfo.CompileTime = ParseConsoleData(response, "Compiled On", ": ", "\n"); + ProgramInfo.Include4Dat = ParseConsoleData(response, "Include4.dat", ": ", "\n"); + + + if (ProgramInfo.ProgramFile.Contains(".dll")) + { + // SSP Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n"); + ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n"); + ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n"); + ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ", + "\n"); + ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n"); + } + else if (ProgramInfo.ProgramFile.Contains(".smw")) + { + // SIMPL Windows Program + ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ":", "\n"); + ProgramInfo.SystemName = ParseConsoleData(response, "System Name", ": ", "\n"); + ProgramInfo.CrestronDb = ParseConsoleData(response, "CrestronDB", ": ", "\n"); + ProgramInfo.Environment = ParseConsoleData(response, "Source Env", ": ", "\n"); + ProgramInfo.Programmer = ParseConsoleData(response, "Programmer", ": ", "\n"); + } + Debug.Console(2, "Program info for slot {0} successfully updated", Program.Number); + + UpdateFeedbacks(); + } + + private void UpdateFeedbacks() + { + ProgramNameFeedback.FireUpdate(); + ProgramCompileTimeFeedback.FireUpdate(); + CrestronDataBaseVersionFeedback.FireUpdate(); + EnvironmentVersionFeedback.FireUpdate(); + + AggregatedProgramInfoFeedback.FireUpdate(); + + OnProgramInfoChanged(); } public void OnProgramInfoChanged() @@ -294,30 +526,28 @@ namespace PepperDash.Essentials.Core.Monitoring private string ParseConsoleData(string data, string line, string startString, string endString) { - string outputData = ""; + var outputData = ""; - if (data.Length > 0) + if (data.Length <= 0) return outputData; + + try { - try - { - - //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); - var linePosition = data.IndexOf(line); - var startPosition = data.IndexOf(startString, linePosition) + startString.Length; - var endPosition = data.IndexOf(endString, startPosition); - outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); - //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); - } - catch (Exception e) - { - Debug.Console(1, "Error Parsing Console Data:\r{0}", e); - } + //Debug.Console(2, "ParseConsoleData Data: {0}, Line {1}, startStirng {2}, endString {3}", data, line, startString, endString); + var linePosition = data.IndexOf(line, StringComparison.Ordinal); + var startPosition = data.IndexOf(startString, linePosition, StringComparison.Ordinal) + + startString.Length; + var endPosition = data.IndexOf(endString, startPosition, StringComparison.Ordinal); + outputData = data.Substring(startPosition, endPosition - startPosition).Trim(); + //Debug.Console(2, "ParseConsoleData Return: {0}", outputData); + } + catch (Exception e) + { + Debug.Console(1, "Error Parsing Console Data:\r{0}", e); } return outputData; } } - } /// @@ -330,32 +560,39 @@ namespace PepperDash.Essentials.Core.Monitoring [JsonProperty("programNumber")] public uint ProgramNumber { get; private set; } - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof (StringEnumConverter))] [JsonProperty("operatingState")] public eProgramOperatingState OperatingState { get; set; } - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof (StringEnumConverter))] [JsonProperty("registrationState")] public eProgramRegistrationState RegistrationState { get; set; } [JsonProperty("programFile")] public string ProgramFile { get; set; } + [JsonProperty("friendlyName")] public string FriendlyName { get; set; } + [JsonProperty("compilerRevision")] public string CompilerRevision { get; set; } + [JsonProperty("compileTime")] public string CompileTime { get; set; } + [JsonProperty("include4Dat")] public string Include4Dat { get; set; } // SIMPL Windows properties [JsonProperty("systemName")] public string SystemName { get; set; } + [JsonProperty("crestronDb")] - public string CrestronDB { get; set; } + public string CrestronDb { get; set; } + [JsonProperty("environment")] public string Environment { get; set; } + [JsonProperty("programmer")] public string Programmer { get; set; } @@ -363,10 +600,13 @@ namespace PepperDash.Essentials.Core.Monitoring // SSP Properties [JsonProperty("applicationName")] public string ApplicationName { get; set; } + [JsonProperty("programTool")] public string ProgramTool { get; set; } + [JsonProperty("minFirmwareVersion")] public string MinFirmwareVersion { get; set; } + [JsonProperty("plugInVersion")] public string PlugInVersion { get; set; } @@ -381,7 +621,7 @@ namespace PepperDash.Essentials.Core.Monitoring Include4Dat = ""; SystemName = ""; - CrestronDB = ""; + CrestronDb = ""; Environment = ""; Programmer = ""; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index fe721fba..9dbf7000 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -131,6 +131,7 @@ + @@ -237,6 +238,7 @@ + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SSMonoIOLibrary.clz b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SSMonoIOLibrary.clz deleted file mode 100644 index 1166c23e..00000000 Binary files a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SSMonoIOLibrary.clz and /dev/null differ diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SSMonoIOLibrary.config b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SSMonoIOLibrary.config deleted file mode 100644 index d1d099df..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SSMonoIOLibrary.config +++ /dev/null @@ -1,16 +0,0 @@ - - - SSMonoIOLibrary - SSMonoIOLibrary - SSMonoIOLibrary - 1.007.0017 - SIMPL# Plugin - 5 - 5 - - - - 4/6/2016 7:49:24 AM - 1.0.0.14081 - - \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SimplSharpData.dat b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SimplSharpData.dat deleted file mode 100644 index 816bfe12..00000000 Binary files a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/SimplSharpData.dat and /dev/null differ diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/manifest.info b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/manifest.info deleted file mode 100644 index 99eb2339..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/manifest.info +++ /dev/null @@ -1,18 +0,0 @@ -MainAssembly=SSMonoIOLibrary.dll:6c69af117dca3f74ebca99f7a0e3181c -MainAssemblyMinFirmwareVersion=1.007.0017 -ü -DependencySource=SimplSharpCustomAttributesInterface.dll:9c4b4d4c519b655af90016edca2d66b9 -DependencyPath=SSMonoIOLibrary.clz:SimplSharpCustomAttributesInterface.dll -DependencyMainAssembly=SimplSharpCustomAttributesInterface.dll:9c4b4d4c519b655af90016edca2d66b9 -ü -DependencySource=SimplSharpHelperInterface.dll:aed72eb0e19559a3f56708be76445dcd -DependencyPath=SSMonoIOLibrary.clz:SimplSharpHelperInterface.dll -DependencyMainAssembly=SimplSharpHelperInterface.dll:aed72eb0e19559a3f56708be76445dcd -ü -DependencySource=SimplSharpReflectionInterface.dll:e3ff8edbba84ccd7155b9984e67488b2 -DependencyPath=SSMonoIOLibrary.clz:SimplSharpReflectionInterface.dll -DependencyMainAssembly=SimplSharpReflectionInterface.dll:e3ff8edbba84ccd7155b9984e67488b2 -ü -DependencySource=SSharpCrestronExtensionsLibrary.dll:655a49edee523f150d1c03bcb5db87d0 -DependencyPath=SSMonoIOLibrary.clz:SSharpCrestronExtensionsLibrary.dll -DependencyMainAssembly=SSharpCrestronExtensionsLibrary.dll:655a49edee523f150d1c03bcb5db87d0 diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/manifest.ser b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/manifest.ser deleted file mode 100644 index ac2eb253..00000000 Binary files a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoIOLibrary.clz/manifest.ser and /dev/null differ diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SSMonoProTaskLibrary.config b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SSMonoProTaskLibrary.config deleted file mode 100644 index 3b250815..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SSMonoProTaskLibrary.config +++ /dev/null @@ -1,16 +0,0 @@ - - - SSMonoProTaskLibrary - SSMonoProTaskLibrary - SSMonoProTaskLibrary - 1.009.0029 - SIMPL# Plugin - 5 - 5 - - - - 4/6/2016 7:55:41 AM - 1.0.0.14269 - - \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SSMonoProTaskLibrary.cplz b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SSMonoProTaskLibrary.cplz deleted file mode 100644 index 927a567e..00000000 Binary files a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SSMonoProTaskLibrary.cplz and /dev/null differ diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SimplSharpData.dat b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SimplSharpData.dat deleted file mode 100644 index 816bfe12..00000000 Binary files a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/SimplSharpData.dat and /dev/null differ diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/manifest.info b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/manifest.info deleted file mode 100644 index 821d5130..00000000 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/manifest.info +++ /dev/null @@ -1,30 +0,0 @@ -MainAssembly=SSMonoProTaskLibrary.dll:5d3a301400516bd812bf1566c72ccbf2 -MainAssemblyMinFirmwareVersion=1.009.0029 -ü -DependencySource=SimplSharpReflectionInterface.dll:e3ff8edbba84ccd7155b9984e67488b2 -DependencyPath=SSMonoProTaskLibrary.cplz:SimplSharpReflectionInterface.dll -DependencyMainAssembly=SimplSharpReflectionInterface.dll:e3ff8edbba84ccd7155b9984e67488b2 -ü -DependencySource=SSharpCrestronExtensionsLibrary.dll:776d0247d8d42164c46c7cc1dfadbd03 -DependencyPath=SSMonoProTaskLibrary.cplz:SSharpCrestronExtensionsLibrary.dll -DependencyMainAssembly=SSharpCrestronExtensionsLibrary.dll:776d0247d8d42164c46c7cc1dfadbd03 -ü -DependencySource=SSMonoConcurrentCollectionsLibrary.dll:b0afcd989b081899c9eb29f9e4c8b799 -DependencyPath=SSMonoProTaskLibrary.cplz:SSMonoConcurrentCollectionsLibrary.dll -DependencyMainAssembly=SSMonoConcurrentCollectionsLibrary.dll:b0afcd989b081899c9eb29f9e4c8b799 -ü -DependencySource=SSMonoProConcurrentCollectionsLibrary.dll:8b718ce29f938bbf9cb5b8fc2d89332f -DependencyPath=SSMonoProTaskLibrary.cplz:SSMonoProConcurrentCollectionsLibrary.dll -DependencyMainAssembly=SSMonoProConcurrentCollectionsLibrary.dll:8b718ce29f938bbf9cb5b8fc2d89332f -ü -DependencySource=SSMonoSupportLibrary.dll:59362515f2c1d61583b2e40793987917 -DependencyPath=SSMonoProTaskLibrary.cplz:SSMonoSupportLibrary.dll -DependencyMainAssembly=SSMonoSupportLibrary.dll:59362515f2c1d61583b2e40793987917 -ü -DependencySource=SSMonoThreadingLibrary.dll:ea2ae2e1d9c425236f39de9192591062 -DependencyPath=SSMonoProTaskLibrary.cplz:SSMonoThreadingLibrary.dll -DependencyMainAssembly=SSMonoThreadingLibrary.dll:ea2ae2e1d9c425236f39de9192591062 -ü -DependencySource=SSMonoTupleLibrary.dll:2a3b419fff4199838079879053fcb41d -DependencyPath=SSMonoProTaskLibrary.cplz:SSMonoTupleLibrary.dll -DependencyMainAssembly=SSMonoTupleLibrary.dll:2a3b419fff4199838079879053fcb41d diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/manifest.ser b/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/manifest.ser deleted file mode 100644 index d24ab36c..00000000 Binary files a/essentials-framework/Essentials Core/PepperDashEssentialsBase/References/SSMonoProTaskLibrary.cplz/manifest.ser and /dev/null differ diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs index 4878a206..aabd6436 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Timers/CountdownTimer.cs @@ -1,138 +1,149 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; - -namespace PepperDash.Essentials.Core -{ - public class SecondsCountdownTimer: IKeyed - { - public event EventHandler HasStarted; - public event EventHandler HasFinished; - public event EventHandler WasCancelled; - - public string Key { get; private set; } - - public BoolFeedback IsRunningFeedback { get; private set; } - bool _IsRunning; - - public IntFeedback PercentFeedback { get; private set; } - public StringFeedback TimeRemainingFeedback { get; private set; } - - public bool CountsDown { get; set; } - - /// - /// The number of seconds to countdown - /// - public int SecondsToCount { get; set; } - - public DateTime StartTime { get; private set; } - public DateTime FinishTime { get; private set; } - - CTimer SecondTimer; - - /// - /// Constructor - /// - /// - public SecondsCountdownTimer(string key) - { - Key = key; - IsRunningFeedback = new BoolFeedback(() => _IsRunning); - - TimeRemainingFeedback = new StringFeedback(() => - { - // Need to handle up and down here. - - if (StartTime == null || FinishTime == null) - return ""; - var timeSpan = FinishTime - DateTime.Now; - return Math.Round(timeSpan.TotalSeconds).ToString(); - }); - - PercentFeedback = new IntFeedback(() => - { - if (StartTime == null || FinishTime == null) - return 0; - double percent = (FinishTime - DateTime.Now).TotalSeconds - / (FinishTime - StartTime).TotalSeconds - * 100; - return (int)percent; - }); - } - - /// - /// Starts the Timer - /// - public void Start() - { - if (_IsRunning) - return; - StartTime = DateTime.Now; - FinishTime = StartTime + TimeSpan.FromSeconds(SecondsToCount); - - if (SecondTimer != null) - SecondTimer.Stop(); - SecondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000); - _IsRunning = true; - IsRunningFeedback.FireUpdate(); - - var handler = HasStarted; - if (handler != null) - handler(this, new EventArgs()); - } - - /// - /// Restarts the timer - /// - public void Reset() - { - _IsRunning = false; - Start(); - } - - /// - /// Cancels the timer (without triggering it to finish) - /// - public void Cancel() - { - StopHelper(); - - var handler = WasCancelled; - if (handler != null) - handler(this, new EventArgs()); - } - - /// - /// Called upon expiration, or calling this will force timer to finish. - /// - public void Finish() - { - StopHelper(); - - var handler = HasFinished; - if (handler != null) - handler(this, new EventArgs()); - } - - void StopHelper() - { - if (SecondTimer != null) - SecondTimer.Stop(); - _IsRunning = false; - IsRunningFeedback.FireUpdate(); - } - - void SecondElapsedTimerCallback(object o) - { - PercentFeedback.FireUpdate(); - TimeRemainingFeedback.FireUpdate(); - - if (DateTime.Now >= FinishTime) - Finish(); - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; + +namespace PepperDash.Essentials.Core +{ + public class SecondsCountdownTimer: IKeyed + { + public event EventHandler HasStarted; + public event EventHandler HasFinished; + public event EventHandler WasCancelled; + + public string Key { get; private set; } + + public BoolFeedback IsRunningFeedback { get; private set; } + bool _IsRunning; + + public IntFeedback PercentFeedback { get; private set; } + public StringFeedback TimeRemainingFeedback { get; private set; } + + public bool CountsDown { get; set; } + + /// + /// The number of seconds to countdown + /// + public int SecondsToCount { get; set; } + + public DateTime StartTime { get; private set; } + public DateTime FinishTime { get; private set; } + + CTimer SecondTimer; + + /// + /// Constructor + /// + /// + public SecondsCountdownTimer(string key) + { + Key = key; + IsRunningFeedback = new BoolFeedback(() => _IsRunning); + + TimeRemainingFeedback = new StringFeedback(() => + { + // Need to handle up and down here. + + if (StartTime == null || FinishTime == null) + return ""; + var timeSpan = FinishTime - DateTime.Now; + + if (timeSpan.TotalSeconds < 60) + { + return Math.Round(timeSpan.TotalSeconds).ToString(); + } + else + { + Debug.Console(2, this, "timeSpan.Minutes == {0}, timeSpan.Seconds == {1}", timeSpan.Minutes, timeSpan.Seconds); + return String.Format("{0:D2}:{1:D2}", + timeSpan.Minutes, + timeSpan.Seconds); + } + }); + + PercentFeedback = new IntFeedback(() => + { + if (StartTime == null || FinishTime == null) + return 0; + double percent = (FinishTime - DateTime.Now).TotalSeconds + / (FinishTime - StartTime).TotalSeconds + * 100; + return (int)percent; + }); + } + + /// + /// Starts the Timer + /// + public void Start() + { + if (_IsRunning) + return; + StartTime = DateTime.Now; + FinishTime = StartTime + TimeSpan.FromSeconds(SecondsToCount); + + if (SecondTimer != null) + SecondTimer.Stop(); + SecondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000); + _IsRunning = true; + IsRunningFeedback.FireUpdate(); + + var handler = HasStarted; + if (handler != null) + handler(this, new EventArgs()); + } + + /// + /// Restarts the timer + /// + public void Reset() + { + _IsRunning = false; + Start(); + } + + /// + /// Cancels the timer (without triggering it to finish) + /// + public void Cancel() + { + StopHelper(); + + var handler = WasCancelled; + if (handler != null) + handler(this, new EventArgs()); + } + + /// + /// Called upon expiration, or calling this will force timer to finish. + /// + public void Finish() + { + StopHelper(); + + var handler = HasFinished; + if (handler != null) + handler(this, new EventArgs()); + } + + void StopHelper() + { + if (SecondTimer != null) + SecondTimer.Stop(); + _IsRunning = false; + IsRunningFeedback.FireUpdate(); + } + + void SecondElapsedTimerCallback(object o) + { + PercentFeedback.FireUpdate(); + TimeRemainingFeedback.FireUpdate(); + + if (DateTime.Now >= FinishTime) + Finish(); + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs new file mode 100644 index 00000000..6c648a29 --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Core.Touchpanels +{ + /// + /// A wrapper class for the touchpanel portion of an MPC3 class process to allow for configurable + /// behavior of the keybad buttons + /// + public class Mpc3TouchpanelController : Device + { + MPC3Basic _Touchpanel; + + Dictionary _Buttons; + + public Mpc3TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary buttons) + : base(key, name) + { + _Touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic; + _Buttons = buttons; + + _Touchpanel.ButtonStateChange += new Crestron.SimplSharpPro.DeviceSupport.ButtonEventHandler(_Touchpanel_ButtonStateChange); + + + AddPostActivationAction(() => + { + // Link up the button feedbacks to the specified BoolFeedbacks + foreach (var button in _Buttons) + { + var feedbackConfig = button.Value.Feedback; + var device = DeviceManager.GetDeviceForKey(feedbackConfig.DeviceKey) as Device; + if (device != null) + { + var bKey = button.Key.ToLower(); + + var feedback = device.GetFeedbackProperty(feedbackConfig.BoolFeedbackName); + + var bFeedback = feedback as BoolFeedback; + var iFeedback = feedback as IntFeedback; + if (bFeedback != null) + { + + if (bKey == "power") + { + bFeedback.LinkCrestronFeedback(_Touchpanel.FeedbackPower); + continue; + } + else if (bKey == "mute") + { + bFeedback.LinkCrestronFeedback(_Touchpanel.FeedbackMute); + continue; + } + + // Link to the Crestron Feedback corresponding to the button number + bFeedback.LinkCrestronFeedback(_Touchpanel.Feedbacks[UInt16.Parse(button.Key)]); + } + else if (iFeedback != null) + { + if (bKey == "volumefeedback") + { + var volFeedback = feedback as IntFeedback; + // TODO: Figure out how to subsribe to a volume IntFeedback and link it to the voluem + volFeedback.LinkInputSig(_Touchpanel.VolumeBargraph); + } + } + else + { + Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.BoolFeedbackName, device.Key); + } + } + else + { + Debug.Console(1, this, "Unable to get device with key: {0}", feedbackConfig.DeviceKey); + } + } + }); + } + + void _Touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args) + { + Debug.Console(1, this, "Button {0} ({1}), {2}", args.Button.Number, args.Button.Name, args.NewButtonState); + var type = args.NewButtonState.ToString(); + + if (_Buttons.ContainsKey(args.Button.Number.ToString())) + { + Press(args.Button.Number.ToString(), type); + } + else if(_Buttons.ContainsKey(args.Button.Name.ToString())) + { + Press(args.Button.Name.ToString(), type); + } + } + + /// + /// Runs the function associated with this button/type. One of the following strings: + /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased + /// + /// + /// + public void Press(string number, string type) + { + // TODO: In future, consider modifying this to generate actions at device activation time + // to prevent the need to dynamically call the method via reflection on each button press + if (!_Buttons.ContainsKey(number)) { return; } + var but = _Buttons[number]; + if (but.EventTypes.ContainsKey(type)) + { + foreach (var a in but.EventTypes[type]) { DeviceJsonApi.DoDeviceAction(a); } + } + } + + + } + + /// + /// Represents the configuration of a keybad buggon + /// + public class KeypadButton + { + public Dictionary EventTypes { get; set; } + public KeypadButtonFeedback Feedback { get; set; } + + public KeypadButton() + { + EventTypes = new Dictionary(); + Feedback = new KeypadButtonFeedback(); + } + } + + /// + /// + /// + public class KeypadButtonFeedback + { + public string DeviceKey { get; set; } + public string BoolFeedbackName { get; set; } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs b/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs index 1624ec5f..28358a51 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs @@ -44,7 +44,10 @@ namespace PepperDash.Essentials.DM.AirMedia DeviceConfig = dc; - PropertiesConfig = props; + PropertiesConfig = props; + + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this)); diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs index d0a6ba63..033d6a54 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs @@ -1,1027 +1,1003 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.DM; -using Crestron.SimplSharpPro.DM.Cards; -using Crestron.SimplSharpPro.DM.Endpoints; -using Crestron.SimplSharpPro.DM.Endpoints.Receivers; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -//using PepperDash.Essentials.DM.Cards; - -using PepperDash.Essentials.DM.Config; - -namespace PepperDash.Essentials.DM -{ - /// - /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions - /// - /// - public class DmChassisController : CrestronGenericBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback - { - public DMChassisPropertiesConfig PropertiesConfig { get; set; } - - public Switch Chassis { get; private set; } - - // Feedbacks for EssentialDM - public Dictionary VideoOutputFeedbacks { get; private set; } - public Dictionary AudioOutputFeedbacks { get; private set; } - public Dictionary VideoInputSyncFeedbacks { get; private set; } - public Dictionary InputEndpointOnlineFeedbacks { get; private set; } - public Dictionary OutputEndpointOnlineFeedbacks { get; private set; } - public Dictionary InputNameFeedbacks { get; private set; } - public Dictionary OutputNameFeedbacks { get; private set; } - public Dictionary OutputVideoRouteNameFeedbacks { get; private set; } - public Dictionary OutputAudioRouteNameFeedbacks { get; private set; } - public Dictionary UsbOutputRoutedToFeebacks { get; private set; } - public Dictionary UsbInputRoutedToFeebacks { get; private set; } - - public IntFeedback SystemIdFeebdack { get; private set; } - public BoolFeedback SystemIdBusyFeedback { get; private set; } - - - public Dictionary InputCardHdcpCapabilityFeedbacks { get; private set; } - - public Dictionary InputCardHdcpCapabilityTypes { get; private set; } - - - // Need a couple Lists of generic Backplane ports - public RoutingPortCollection InputPorts { get; private set; } - public RoutingPortCollection OutputPorts { get; private set; } - - public Dictionary TxDictionary { get; set; } - public Dictionary RxDictionary { get; set; } - - //public Dictionary InputCards { get; private set; } - //public Dictionary OutputCards { get; private set; } - - public Dictionary InputNames { get; set; } - public Dictionary OutputNames { get; set; } - public Dictionary VolumeControls { get; private set; } - - public const int RouteOffTime = 500; - Dictionary RouteOffTimers = new Dictionary(); - - /// - /// Text that represents when an output has no source routed to it - /// - public string NoRouteText = ""; - - /// - /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now - /// - public static DmChassisController GetDmChassisController(string key, string name, - string type, DMChassisPropertiesConfig properties) - { - try - { - type = type.ToLower(); - uint ipid = properties.Control.IpIdInt; - - DmMDMnxn chassis = null; - if (type == "dmmd8x8") { chassis = new DmMd8x8(ipid, Global.ControlSystem); } - else if (type == "dmmd8x8rps") { chassis = new DmMd8x8rps(ipid, Global.ControlSystem); } - else if (type == "dmmd8x8cpu3") { chassis = new DmMd8x8Cpu3(ipid, Global.ControlSystem); } - else if (type == "dmmd8x8cpu3rps") { chassis = new DmMd8x8Cpu3rps(ipid, Global.ControlSystem); } - - else if (type == "dmmd16x16") { chassis = new DmMd16x16(ipid, Global.ControlSystem); } - else if (type == "dmmd16x16rps") { chassis = new DmMd16x16rps(ipid, Global.ControlSystem); } - else if (type == "dmmd16x16cpu3") { chassis = new DmMd16x16Cpu3(ipid, Global.ControlSystem); } - else if (type == "dmmd16x16cpu3rps") { chassis = new DmMd16x16Cpu3rps(ipid, Global.ControlSystem); } - - else if (type == "dmmd32x32") { chassis = new DmMd32x32(ipid, Global.ControlSystem); } - else if (type == "dmmd32x32rps") { chassis = new DmMd32x32rps(ipid, Global.ControlSystem); } - else if (type == "dmmd32x32cpu3") { chassis = new DmMd32x32Cpu3(ipid, Global.ControlSystem); } - else if (type == "dmmd32x32cpu3rps") { chassis = new DmMd32x32Cpu3rps(ipid, Global.ControlSystem); } - - if (chassis == null) - { - return null; - } - - var controller = new DmChassisController(key, name, chassis); - - // add the cards and port names - foreach (var kvp in properties.InputSlots) - { - controller.AddInputCard(kvp.Value, kvp.Key); - } - foreach (var kvp in properties.OutputSlots) - { - controller.AddOutputCard(kvp.Value, kvp.Key); - } - - foreach (var kvp in properties.VolumeControls) - { - // get the card - // check it for an audio-compatible type - // make a something-something that will make it work - // retire to mountain village - var outNum = kvp.Key; - var card = controller.Chassis.Outputs[outNum].Card; - Audio.Output audio = null; - if (card is DmcHdo) - audio = (card as DmcHdo).Audio; - else if (card is Dmc4kHdo) - audio = (card as Dmc4kHdo).Audio; - if (audio == null) - continue; - // wire up the audio to something here... - controller.AddVolumeControl(outNum, audio); - } - - controller.InputNames = properties.InputNames; - controller.OutputNames = properties.OutputNames; - - if (!string.IsNullOrEmpty(properties.NoRouteText)) - { - controller.NoRouteText = properties.NoRouteText; - Debug.Console(1, controller, "Setting No Route Text value to: {0}", controller.NoRouteText); - } - else - Debug.Console(1, controller, "NoRouteText not specified. Defaulting to blank string.", controller.NoRouteText); - - controller.PropertiesConfig = properties; - return controller; - } - catch (System.Exception e) - { - Debug.Console(0, "Error creating DM chassis:\r{0}", e); - } - return null; - } - - - /// - /// - /// - /// - /// - /// - public DmChassisController(string key, string name, DmMDMnxn chassis) - : base(key, name, chassis) - { - Chassis = chassis; - InputPorts = new RoutingPortCollection(); - OutputPorts = new RoutingPortCollection(); - VolumeControls = new Dictionary(); - TxDictionary = new Dictionary(); - RxDictionary = new Dictionary(); - IsOnline.OutputChange += new EventHandler(IsOnline_OutputChange); - Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); - Chassis.DMSystemChange += new DMSystemEventHandler(Chassis_DMSystemChange); - Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); - VideoOutputFeedbacks = new Dictionary(); - AudioOutputFeedbacks = new Dictionary(); - UsbOutputRoutedToFeebacks = new Dictionary(); - UsbInputRoutedToFeebacks = new Dictionary(); - VideoInputSyncFeedbacks = new Dictionary(); - InputNameFeedbacks = new Dictionary(); - OutputNameFeedbacks = new Dictionary(); - OutputVideoRouteNameFeedbacks = new Dictionary(); - OutputAudioRouteNameFeedbacks = new Dictionary(); - InputEndpointOnlineFeedbacks = new Dictionary(); - OutputEndpointOnlineFeedbacks = new Dictionary(); - - SystemIdFeebdack = new IntFeedback(() => { return (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue; }); - SystemIdBusyFeedback = new BoolFeedback(() => { return (Chassis as DmMDMnxn).SystemIdBusy.BoolValue; }); - InputCardHdcpCapabilityFeedbacks = new Dictionary(); - InputCardHdcpCapabilityTypes = new Dictionary(); - } - - public override bool CustomActivate() - { - Debug.Console(2, this, "Setting up feedbacks."); - - // Setup Output Card Feedbacks - for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) - { - var tempX = x; - - Debug.Console(2, this, "Setting up feedbacks for output slot: {0}", tempX); - - if (Chassis.Outputs[tempX] != null) - { - VideoOutputFeedbacks[tempX] = new IntFeedback(() => - { - if (Chassis.Outputs[tempX].VideoOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; } - else { return 0; }; - }); - AudioOutputFeedbacks[tempX] = new IntFeedback(() => - { - if (Chassis.Outputs[tempX].AudioOutFeedback != null) { return (ushort)Chassis.Outputs[tempX].AudioOutFeedback.Number; } - else { return 0; }; - }); - UsbOutputRoutedToFeebacks[tempX] = new IntFeedback(() => - { - if (Chassis.Outputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Outputs[tempX].USBRoutedToFeedback.Number; } - else { return 0; }; - }); - - OutputNameFeedbacks[tempX] = new StringFeedback(() => - { - if (Chassis.Outputs[tempX].NameFeedback != null) - { - return Chassis.Outputs[tempX].NameFeedback.StringValue; - } - else - { - return ""; - } - }); - OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => - { - if (Chassis.Outputs[tempX].VideoOutFeedback != null) - { - return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; - } - else - { - return NoRouteText; - } - }); - OutputAudioRouteNameFeedbacks[tempX] = new StringFeedback(() => - { - if (Chassis.Outputs[tempX].AudioOutFeedback != null) - { - return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue; - } - else - { - return NoRouteText; - - } - }); - - OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => - { - return Chassis.Outputs[tempX].EndpointOnlineFeedback; - }); - } - else - { - Debug.Console(2, this, "No Output Card defined in slot: {0}", tempX); - } - }; - - // Setup Input Card Feedbacks - for (uint x = 1; x <= Chassis.NumberOfInputs; x++) - { - var tempX = x; - - Debug.Console(2, this, "Setting up feedbacks for input slot: {0}", tempX); - - CheckForHdcp2Property(tempX); - - if (Chassis.Inputs[tempX] != null) - { - - UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => - { - if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) { return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; } - else { return 0; }; - }); - VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => - { - if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) - return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; - else - return false; - }); - InputNameFeedbacks[tempX] = new StringFeedback(() => - { - if (Chassis.Inputs[tempX].NameFeedback != null) - { - return Chassis.Inputs[tempX].NameFeedback.StringValue; - } - else - { - return ""; - } - }); - - InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => - { - return Chassis.Inputs[tempX].EndpointOnlineFeedback; - }); - - InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => - { - var inputCard = Chassis.Inputs[tempX]; - - Debug.Console(2, this, "Adding InputCardHdcpCapabilityFeedback for slot: {0}", inputCard); - - if (inputCard.Card is DmcHd) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - - if ((inputCard.Card as DmcHd).HdmiInput.HdcpSupportOnFeedback.BoolValue) - return 1; - else - return 0; - } - else if (inputCard.Card is DmcHdDsp) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - - if ((inputCard.Card as DmcHdDsp).HdmiInput.HdcpSupportOnFeedback.BoolValue) - return 1; - else - return 0; - } - else if (inputCard.Card is Dmc4kHdBase) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; - - return (int)(inputCard.Card as Dmc4kHdBase).HdmiInput.HdcpReceiveCapability; - } - else if (inputCard.Card is Dmc4kCBase) - { - if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - - return (int)(inputCard.Card as Dmc4kCBase).DmInput.HdcpReceiveCapability; - } - else if ((inputCard.Card as Dmc4kCBase).DmInput.HdcpSupportOnFeedback.BoolValue) - return 1; - else - return 0; - } - else if (inputCard.Card is Dmc4kCDspBase) - { - if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) - { - InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; - - return (int)(inputCard.Card as Dmc4kCDspBase).DmInput.HdcpReceiveCapability; - } - else if ((inputCard.Card as Dmc4kCDspBase).DmInput.HdcpSupportOnFeedback.BoolValue) - return 1; - else - return 0; - } - else - return 0; - }); - } - else - { - Debug.Console(2, this, "No Input Card defined in slot: {0}", tempX); - } - } - - return base.CustomActivate(); - } - - /// - /// Checks for presence of config property defining if the input card supports HDCP2. - /// If not found, assumes false. - /// - /// Input Slot - void CheckForHdcp2Property(uint inputSlot) - { - if (!PropertiesConfig.InputSlotSupportsHdcp2.ContainsKey(inputSlot)) - { - Debug.Console(0, this, Debug.ErrorLogLevel.Warning, -@"Properties Config does not define inputSlotSupportsHdcp2 entry for input card: {0}. Assuming false. -If HDCP2 is required, HDCP control/feedback will not fucntion correctly!", inputSlot); - PropertiesConfig.InputSlotSupportsHdcp2.Add(inputSlot, false); - } - else - Debug.Console(2, this, "inputSlotSupportsHdcp2 for input card: {0} = {1}", inputSlot, PropertiesConfig.InputSlotSupportsHdcp2[inputSlot]); - } - - /// - /// - /// - /// - /// - public void AddInputCard(string type, uint number) - { - Debug.Console(2, this, "Adding input card '{0}', slot {1}", type, number); - - type = type.ToLower(); - - if (type == "dmchd") - { - var inputCard = new DmcHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmchddsp") - { - var inputCard = new DmcHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4khd") - { - var inputCard = new Dmc4kHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4khddsp") - { - var inputCard = new Dmc4kHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4kzhd") - { - var inputCard = new Dmc4kzHd(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmc4kzhddsp") - { - var inputCard = new Dmc4kzHdDsp(number, this.Chassis); - var cecPort = inputCard.HdmiInput as ICec; - AddHdmiInCardPorts(number, cecPort); - } - else if (type == "dmcc") - { - var inputCard = new DmcC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmccdsp") - { - var inputCard = new DmcCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kc") - { - var inputCard = new Dmc4kC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kcdsp") - { - var inputCard = new Dmc4kCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kzc") - { - var inputCard = new Dmc4kzC(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmc4kzcdsp") - { - var inputCard = new Dmc4kzCDsp(number, this.Chassis); - var cecPort = inputCard.DmInput as ICec; - AddDmInCardPorts(number, cecPort); - } - else if (type == "dmccat") - { - new DmcCat(number, this.Chassis); - AddDmInCardPorts(number); - } - else if (type == "dmccatdsp") - { - new DmcCatDsp(number, this.Chassis); - AddDmInCardPorts(number); - } - else if (type == "dmcs") - { - new DmcS(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcsdsp") - { - new DmcSDsp(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcs2") - { - new DmcS2(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcs2dsp") - { - new DmcS2Dsp(number, Chassis); - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcsdi") - { - new DmcSdi(number, Chassis); - AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi, null); - AddInCardHdmiAndAudioLoopPorts(number); - } - else if (type == "dmcdvi") - { - new DmcDvi(number, Chassis); - AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvga") - { - new DmcVga(number, Chassis); - AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvidbnc") - { - new DmcVidBnc(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvidrcaa") - { - new DmcVidRcaA(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvidrcad") - { - new DmcVidRcaD(number, Chassis); - AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); - AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcvid4") - { - new DmcVid4(number, Chassis); - AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); - AddInCardHdmiLoopPort(number); - } - else if (type == "dmcstr") - { - new DmcStr(number, Chassis); - AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); - AddInCardHdmiAndAudioLoopPorts(number); - } - } - - void AddDmInCardPorts(uint number) - { - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); - AddInCardHdmiAndAudioLoopPorts(number); - } - void AddDmInCardPorts(uint number, ICec cecPort) - { - AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); - AddInCardHdmiAndAudioLoopPorts(number); - } - - void AddHdmiInCardPorts(uint number, ICec cecPort) - { - AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); - AddInCardHdmiAndAudioLoopPorts(number); - } - - void AddInCardHdmiAndAudioLoopPorts(uint number) - { - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null); - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "audioLoopOut", eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null); - } - - void AddInCardHdmiLoopPort(uint number) - { - AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, null); - } - - /// - /// - /// - /// - /// - public void AddOutputCard(string type, uint number) - { - type = type.ToLower(); - - Debug.Console(2, this, "Adding output card '{0}', slot {1}", type, number); - if (type == "dmc4khdo") - { - var outputCard = new Dmc4kHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); - } - else if (type == "dmc4kzhdo") - { - var outputCard = new Dmc4kzHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); - } - else if (type == "dmchdo") - { - var outputCard = new DmcHdoSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - var cecPort2 = outputCard.Card2.HdmiOutput; - AddDmcHdoPorts(number, cecPort1, cecPort2); - } - else if (type == "dmc4kcohd") - { - var outputCard = new Dmc4kCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmc4kzcohd") - { - var outputCard = new Dmc4kzCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmccohd") - { - var outputCard = new DmcCoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmccatohd") - { - var outputCard = new DmcCatoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddDmcCoPorts(number, cecPort1); - } - else if (type == "dmcsohd") - { - var outputCard = new DmcSoHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 2); - - } - else if (type == "dmcs2ohd") - { - var outputCard = new DmcS2oHdSingle(number, Chassis); - var cecPort1 = outputCard.Card1.HdmiOutput; - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 2); - } - else if (type == "dmcstro") - { - var outputCard = new DmcStroSingle(number, Chassis); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming, 2 * (number - 1) + 1); - } - - else - Debug.Console(1, this, " WARNING: Output card type '{0}' is not available", type); - } - - void AddDmcHdoPorts(uint number, ICec cecPort1, ICec cecPort2) - { - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut1", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, 2 * (number - 1) + 1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 2, cecPort2); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut2", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, 2 * (number - 1) + 2); - } - - void AddDmcCoPorts(uint number, ICec cecPort1) - { - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); - AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 2); - } - - - /// - /// Adds InputPort - /// - void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) - { - var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); - - InputPorts.Add(inputPort); - } - - /// - /// Adds InputPort and sets Port as ICec object - /// - void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) - { - var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); - Debug.Console(2, this, "Adding input port '{0}'", portKey); - var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); - - if (inputPort != null) - { - if (cecPort != null) - inputPort.Port = cecPort; - - InputPorts.Add(inputPort); - } - else - Debug.Console(2, this, "inputPort is null"); - } - - /// - /// Adds OutputPort - /// - void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) - { - var portKey = string.Format("{0}--{1}", cardName, portName); - Debug.Console(2, this, "Adding output port '{0}'", portKey); - OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)); - } - - /// - /// Adds OutputPort and sets Port as ICec object - /// - void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) - { - var portKey = string.Format("{0}--{1}", cardName, portName); - Debug.Console(2, this, "Adding output port '{0}'", portKey); - var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); - - if (cecPort != null) - outputPort.Port = cecPort; - - OutputPorts.Add(outputPort); - } - - /// - /// - /// - void AddVolumeControl(uint number, Audio.Output audio) - { - VolumeControls.Add(number, new DmCardAudioOutputController(audio)); - } - - //public void SetInputHdcpSupport(uint input, ePdtHdcpSupport hdcpSetting) - //{ - - //} - - - void Chassis_DMSystemChange(Switch device, DMSystemEventArgs args) - { - switch (args.EventId) - { - case DMSystemEventIds.SystemIdEventId: - { - Debug.Console(2, this, "SystemIdEvent Value: {0}", (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue); - SystemIdFeebdack.FireUpdate(); - break; - } - case DMSystemEventIds.SystemIdBusyEventId: - { - Debug.Console(2, this, "SystemIdBusyEvent State: {0}", (Chassis as DmMDMnxn).SystemIdBusy.BoolValue); - SystemIdBusyFeedback.FireUpdate(); - break; - } - } - } - - void Chassis_DMInputChange(Switch device, DMInputEventArgs args) - { - - switch (args.EventId) { - case DMInputEventIds.EndpointOnlineEventId: - { - Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); - InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.OnlineFeedbackEventId: - { - Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); - InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.VideoDetectedEventId: - { - Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); - VideoInputSyncFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.InputNameEventId: - { - Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); - InputNameFeedbacks[args.Number].FireUpdate(); - break; - } - case DMInputEventIds.UsbRoutedToEventId: - { - Debug.Console(2, this, "DM Input {0} UsbRoutedToEventId", args.Number); - if(UsbInputRoutedToFeebacks[args.Number] != null) - UsbInputRoutedToFeebacks[args.Number].FireUpdate(); - else - Debug.Console(1, this, "No index of {0} found in UsbInputRoutedToFeedbacks"); - break; - } - case DMInputEventIds.HdcpCapabilityFeedbackEventId: - { - Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); - if (InputCardHdcpCapabilityFeedbacks[args.Number] != null) - InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate(); - else - Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); - break; - } - default: - { - Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); - break; - } - } - } - /// - /// - void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) - { - var output = args.Number; - - switch (args.EventId) - { - case DMOutputEventIds.VolumeEventId: - { - if (VolumeControls.ContainsKey(output)) - { - VolumeControls[args.Number].VolumeEventFromChassis(); - } - break; - } - case DMOutputEventIds.EndpointOnlineEventId: - { - Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.OnlineFeedbackEventId: - { - Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); - OutputEndpointOnlineFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.VideoOutEventId: - { - if (Chassis.Outputs[output].VideoOutFeedback != null) - { - Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].VideoOutFeedback.Number, output); - } - if (VideoOutputFeedbacks.ContainsKey(output)) - { - VideoOutputFeedbacks[output].FireUpdate(); - - } - if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) - { - OutputVideoRouteNameFeedbacks[output].FireUpdate(); - } - break; - } - case DMOutputEventIds.AudioOutEventId: - { - if (Chassis.Outputs[output].AudioOutFeedback != null) - { - Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].AudioOutFeedback.Number, output); - } - if (AudioOutputFeedbacks.ContainsKey(output)) - { - AudioOutputFeedbacks[output].FireUpdate(); - } - if (OutputAudioRouteNameFeedbacks.ContainsKey(output)) - { - OutputAudioRouteNameFeedbacks[output].FireUpdate(); - } - break; - } - case DMOutputEventIds.OutputNameEventId: - { - Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); - OutputNameFeedbacks[output].FireUpdate(); - break; - } - case DMOutputEventIds.UsbRoutedToEventId: - { - Debug.Console(2, this, "DM Output {0} UsbRoutedToEventId", args.Number); - UsbOutputRoutedToFeebacks[args.Number].FireUpdate(); - break; - } - default: - { - Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); - break; - } - } - - } - - /// - /// - /// - /// - void StartOffTimer(PortNumberType pnt) - { - if (RouteOffTimers.ContainsKey(pnt)) - return; - RouteOffTimers[pnt] = new CTimer(o => - { - ExecuteSwitch(0, pnt.Number, pnt.Type); - }, RouteOffTime); - } - - - // Send out sigs when coming online - void IsOnline_OutputChange(object sender, EventArgs e) - { - if (IsOnline.BoolValue) - { - (Chassis as DmMDMnxn).EnableAudioBreakaway.BoolValue = true; - (Chassis as DmMDMnxn).EnableUSBBreakaway.BoolValue = true; - - if (InputNames != null) - foreach (var kvp in InputNames) - Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; - if (OutputNames != null) - foreach(var kvp in OutputNames) - Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; - } - } - - #region IRouting Members - - public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) - { - Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); - - var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail - var output = Convert.ToUInt32(outputSelector); - // Check to see if there's an off timer waiting on this and if so, cancel - var key = new PortNumberType(output, sigType); - if (input == 0) - { - StartOffTimer(key); - } - else - { - if(RouteOffTimers.ContainsKey(key)) - { - Debug.Console(2, this, "{0} cancelling route off due to new source", output); - RouteOffTimers[key].Stop(); - RouteOffTimers.Remove(key); - } - } - - var inCard = input == 0 ? null : Chassis.Inputs[input]; - var outCard = input == 0 ? null : Chassis.Outputs[output]; - - // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES - if ((sigType | eRoutingSignalType.Video) == eRoutingSignalType.Video) - { - Chassis.VideoEnter.BoolValue = true; - Chassis.Outputs[output].VideoOut = inCard; - } - - if ((sigType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) - { - (Chassis as DmMDMnxn).AudioEnter.BoolValue = true; - Chassis.Outputs[output].AudioOut = inCard; - } - - if ((sigType | eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) - { - Chassis.USBEnter.BoolValue = true; - if (Chassis.Outputs[output] != null) - Chassis.Outputs[output].USBRoutedTo = inCard; - } - - if ((sigType | eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) - { - Chassis.USBEnter.BoolValue = true; - if(Chassis.Inputs[input] != null) - Chassis.Inputs[input].USBRoutedTo = outCard; - } - } - - #endregion - } - - public struct PortNumberType - { - public uint Number { get; private set; } - public eRoutingSignalType Type { get; private set; } - - public PortNumberType(uint number, eRoutingSignalType type) : this() - { - Number = number; - Type = type; - } - } + +using System; +using System.Collections.Generic; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DM; +using Crestron.SimplSharpPro.DM.Cards; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.DM.Config; + +namespace PepperDash.Essentials.DM +{ + /// + /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions + /// + /// + public class DmChassisController : CrestronGenericBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback + { + public DMChassisPropertiesConfig PropertiesConfig { get; set; } + + public Switch Chassis { get; private set; } + + // Feedbacks for EssentialDM + public Dictionary VideoOutputFeedbacks { get; private set; } + public Dictionary AudioOutputFeedbacks { get; private set; } + public Dictionary VideoInputSyncFeedbacks { get; private set; } + public Dictionary InputEndpointOnlineFeedbacks { get; private set; } + public Dictionary OutputEndpointOnlineFeedbacks { get; private set; } + public Dictionary InputNameFeedbacks { get; private set; } + public Dictionary OutputNameFeedbacks { get; private set; } + public Dictionary OutputVideoRouteNameFeedbacks { get; private set; } + public Dictionary OutputAudioRouteNameFeedbacks { get; private set; } + public Dictionary UsbOutputRoutedToFeebacks { get; private set; } + public Dictionary UsbInputRoutedToFeebacks { get; private set; } + public Dictionary OutputDisabledByHdcpFeedbacks { get; private set; } + + public IntFeedback SystemIdFeebdack { get; private set; } + public BoolFeedback SystemIdBusyFeedback { get; private set; } + + public Dictionary InputCardHdcpCapabilityFeedbacks { get; private set; } + + public Dictionary InputCardHdcpCapabilityTypes { get; private set; } + + // Need a couple Lists of generic Backplane ports + public RoutingPortCollection InputPorts { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } + + public Dictionary TxDictionary { get; set; } + public Dictionary RxDictionary { get; set; } + + //public Dictionary InputCards { get; private set; } + //public Dictionary OutputCards { get; private set; } + + public Dictionary InputNames { get; set; } + public Dictionary OutputNames { get; set; } + public Dictionary VolumeControls { get; private set; } + + public const int RouteOffTime = 500; + Dictionary RouteOffTimers = new Dictionary(); + + /// + /// Text that represents when an output has no source routed to it + /// + public string NoRouteText = ""; + + /// + /// Factory method to create a new chassis controller from config data. Limited to 8x8 right now + /// + public static DmChassisController GetDmChassisController(string key, string name, + string type, DMChassisPropertiesConfig properties) + { + try + { + type = type.ToLower(); + uint ipid = properties.Control.IpIdInt; + + DmMDMnxn chassis = null; + switch (type) { + case "dmmd8x8": + chassis = new DmMd8x8(ipid, Global.ControlSystem); + break; + case "dmmd8x8rps": + chassis = new DmMd8x8rps(ipid, Global.ControlSystem); + break; + case "dmmd8x8cpu3": + chassis = new DmMd8x8Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd8x8cpu3rps": + chassis = new DmMd8x8Cpu3rps(ipid, Global.ControlSystem); + break; + case "dmmd16x16": + chassis = new DmMd16x16(ipid, Global.ControlSystem); + break; + case "dmmd16x16rps": + chassis = new DmMd16x16rps(ipid, Global.ControlSystem); + break; + case "dmmd16x16cpu3": + chassis = new DmMd16x16Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd16x16cpu3rps": + chassis = new DmMd16x16Cpu3rps(ipid, Global.ControlSystem); + break; + case "dmmd32x32": + chassis = new DmMd32x32(ipid, Global.ControlSystem); + break; + case "dmmd32x32rps": + chassis = new DmMd32x32rps(ipid, Global.ControlSystem); + break; + case "dmmd32x32cpu3": + chassis = new DmMd32x32Cpu3(ipid, Global.ControlSystem); + break; + case "dmmd32x32cpu3rps": + chassis = new DmMd32x32Cpu3rps(ipid, Global.ControlSystem); + break; + } + + if (chassis == null) + return null; + + var controller = new DmChassisController(key, name, chassis); + + // add the cards and port names + foreach (var kvp in properties.InputSlots) + controller.AddInputCard(kvp.Value, kvp.Key); + + foreach (var kvp in properties.OutputSlots) + controller.AddOutputCard(kvp.Value, kvp.Key); + + foreach (var kvp in properties.VolumeControls) + { + // get the card + // check it for an audio-compatible type + // make a something-something that will make it work + // retire to mountain village + var outNum = kvp.Key; + var card = controller.Chassis.Outputs[outNum].Card; + Audio.Output audio = null; + if (card is DmcHdo) + audio = (card as DmcHdo).Audio; + else if (card is Dmc4kHdo) + audio = (card as Dmc4kHdo).Audio; + if (audio == null) + continue; + + // wire up the audio to something here... + controller.AddVolumeControl(outNum, audio); + } + + controller.InputNames = properties.InputNames; + controller.OutputNames = properties.OutputNames; + + if (!string.IsNullOrEmpty(properties.NoRouteText)) + { + controller.NoRouteText = properties.NoRouteText; + Debug.Console(1, controller, "Setting No Route Text value to: {0}", controller.NoRouteText); + } + else + { + Debug.Console(1, controller, "NoRouteText not specified. Defaulting to blank string.", controller.NoRouteText); + } + + controller.PropertiesConfig = properties; + return controller; + } + catch (Exception e) + { + Debug.Console(0, "Error creating DM chassis:\r{0}", e); + } + + return null; + } + + /// + /// + /// + /// + /// + /// + public DmChassisController(string key, string name, DmMDMnxn chassis) + : base(key, name, chassis) + { + Chassis = chassis; + InputPorts = new RoutingPortCollection(); + OutputPorts = new RoutingPortCollection(); + VolumeControls = new Dictionary(); + TxDictionary = new Dictionary(); + RxDictionary = new Dictionary(); + IsOnline.OutputChange += new EventHandler(IsOnline_OutputChange); + Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); + Chassis.DMSystemChange += new DMSystemEventHandler(Chassis_DMSystemChange); + Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange); + VideoOutputFeedbacks = new Dictionary(); + AudioOutputFeedbacks = new Dictionary(); + UsbOutputRoutedToFeebacks = new Dictionary(); + UsbInputRoutedToFeebacks = new Dictionary(); + OutputDisabledByHdcpFeedbacks = new Dictionary(); + VideoInputSyncFeedbacks = new Dictionary(); + InputNameFeedbacks = new Dictionary(); + OutputNameFeedbacks = new Dictionary(); + OutputVideoRouteNameFeedbacks = new Dictionary(); + OutputAudioRouteNameFeedbacks = new Dictionary(); + InputEndpointOnlineFeedbacks = new Dictionary(); + OutputEndpointOnlineFeedbacks = new Dictionary(); + + SystemIdFeebdack = new IntFeedback(() => { return (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue; }); + SystemIdBusyFeedback = new BoolFeedback(() => { return (Chassis as DmMDMnxn).SystemIdBusy.BoolValue; }); + InputCardHdcpCapabilityFeedbacks = new Dictionary(); + InputCardHdcpCapabilityTypes = new Dictionary(); + + for (uint x = 1; x <= Chassis.NumberOfOutputs; x++) + { + var tempX = x; + + if (Chassis.Outputs[tempX] != null) + { + VideoOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + return (ushort)Chassis.Outputs[tempX].VideoOutFeedback.Number; + + return 0; + }); + AudioOutputFeedbacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].AudioOutFeedback != null) + return (ushort)Chassis.Outputs[tempX].AudioOutFeedback.Number; + + return 0; + }); + UsbOutputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Outputs[tempX].USBRoutedToFeedback != null) + return (ushort)Chassis.Outputs[tempX].USBRoutedToFeedback.Number; + + return 0; + }); + + OutputNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].NameFeedback != null) + return Chassis.Outputs[tempX].NameFeedback.StringValue; + + return ""; + }); + OutputVideoRouteNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].VideoOutFeedback != null) + return Chassis.Outputs[tempX].VideoOutFeedback.NameFeedback.StringValue; + + return NoRouteText; + }); + OutputAudioRouteNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Outputs[tempX].AudioOutFeedback != null) + return Chassis.Outputs[tempX].AudioOutFeedback.NameFeedback.StringValue; + + return NoRouteText; + }); + OutputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => Chassis.Outputs[tempX].EndpointOnlineFeedback); + + OutputDisabledByHdcpFeedbacks[tempX] = new BoolFeedback(() => { + var output = Chassis.Outputs[tempX]; + + var hdmiTxOutput = output as Card.HdmiTx; + if (hdmiTxOutput != null) + return hdmiTxOutput.HdmiOutput.DisabledByHdcp.BoolValue; + + var dmHdmiOutput = output as Card.DmHdmiOutput; + if (dmHdmiOutput != null) + return dmHdmiOutput.DisabledByHdcpFeedback.BoolValue; + + var dmsDmOutAdvanced = output as Card.DmsDmOutAdvanced; + if (dmsDmOutAdvanced != null) + return dmsDmOutAdvanced.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiAudioOutput = output as Card.Dmps3HdmiAudioOutput; + if (dmps3HdmiAudioOutput != null) + return dmps3HdmiAudioOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiOutput = output as Card.Dmps3HdmiOutput; + if (dmps3HdmiOutput != null) + return dmps3HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + var dmps3HdmiOutputBackend = output as Card.Dmps3HdmiOutputBackend; + if (dmps3HdmiOutputBackend != null) + return dmps3HdmiOutputBackend.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + // var hdRx4kX10HdmiOutput = output as HdRx4kX10HdmiOutput; + // if (hdRx4kX10HdmiOutput != null) + // return hdRx4kX10HdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + // var hdMdNxMHdmiOutput = output as HdMdNxMHdmiOutput; + // if (hdMdNxMHdmiOutput != null) + // return hdMdNxMHdmiOutput.HdmiOutputPort.DisabledByHdcpFeedback.BoolValue; + + return false; + }); + } + + if (Chassis.Inputs[tempX] != null) + { + UsbInputRoutedToFeebacks[tempX] = new IntFeedback(() => { + if (Chassis.Inputs[tempX].USBRoutedToFeedback != null) + return (ushort)Chassis.Inputs[tempX].USBRoutedToFeedback.Number; + + return 0; + }); + VideoInputSyncFeedbacks[tempX] = new BoolFeedback(() => { + if (Chassis.Inputs[tempX].VideoDetectedFeedback != null) + return Chassis.Inputs[tempX].VideoDetectedFeedback.BoolValue; + + return false; + }); + InputNameFeedbacks[tempX] = new StringFeedback(() => { + if (Chassis.Inputs[tempX].NameFeedback != null) + return Chassis.Inputs[tempX].NameFeedback.StringValue; + + return ""; + }); + + InputEndpointOnlineFeedbacks[tempX] = new BoolFeedback(() => { return Chassis.Inputs[tempX].EndpointOnlineFeedback; }); + + InputCardHdcpCapabilityFeedbacks[tempX] = new IntFeedback(() => { + var inputCard = Chassis.Inputs[tempX]; + + if (inputCard.Card is DmcHd) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + + if ((inputCard.Card as DmcHd).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + + if (inputCard.Card is DmcHdDsp) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + + if ((inputCard.Card as DmcHdDsp).HdmiInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + if (inputCard.Card is Dmc4kHdBase) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.Hdcp2_2Support; + return (int)(inputCard.Card as Dmc4kHdBase).HdmiInput.HdcpReceiveCapability; + } + if (inputCard.Card is Dmc4kCBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + return (int)(inputCard.Card as Dmc4kCBase).DmInput.HdcpReceiveCapability; + } + + if ((inputCard.Card as Dmc4kCBase).DmInput.HdcpSupportOnFeedback.BoolValue) + return 1; + return 0; + } + if (inputCard.Card is Dmc4kCDspBase) + { + if (PropertiesConfig.InputSlotSupportsHdcp2[tempX]) + { + InputCardHdcpCapabilityTypes[tempX] = eHdcpCapabilityType.HdcpAutoSupport; + return (int)(inputCard.Card as Dmc4kCDspBase).DmInput.HdcpReceiveCapability; + } + + if ((inputCard.Card as Dmc4kCDspBase).DmInput.HdcpSupportOnFeedback.BoolValue) + return 1; + + return 0; + } + return 0; + }); + } + } + } + + /// + /// + /// + /// + /// + public void AddInputCard(string type, uint number) + { + Debug.Console(2, this, "Adding input card '{0}', slot {1}", type, number); + + type = type.ToLower(); + + if (type == "dmchd") + { + var inputCard = new DmcHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmchddsp") + { + var inputCard = new DmcHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4khd") + { + var inputCard = new Dmc4kHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4khddsp") + { + var inputCard = new Dmc4kHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4kzhd") + { + var inputCard = new Dmc4kzHd(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmc4kzhddsp") + { + var inputCard = new Dmc4kzHdDsp(number, this.Chassis); + var cecPort = inputCard.HdmiInput as ICec; + AddHdmiInCardPorts(number, cecPort); + } + else if (type == "dmcc") + { + var inputCard = new DmcC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmccdsp") + { + var inputCard = new DmcCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kc") + { + var inputCard = new Dmc4kC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kcdsp") + { + var inputCard = new Dmc4kCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kzc") + { + var inputCard = new Dmc4kzC(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmc4kzcdsp") + { + var inputCard = new Dmc4kzCDsp(number, this.Chassis); + var cecPort = inputCard.DmInput as ICec; + AddDmInCardPorts(number, cecPort); + } + else if (type == "dmccat") + { + new DmcCat(number, this.Chassis); + AddDmInCardPorts(number); + } + else if (type == "dmccatdsp") + { + new DmcCatDsp(number, this.Chassis); + AddDmInCardPorts(number); + } + else if (type == "dmcs") + { + new DmcS(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcsdsp") + { + new DmcSDsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcs2") + { + new DmcS2(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcs2dsp") + { + new DmcS2Dsp(number, Chassis); + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcsdi") + { + new DmcSdi(number, Chassis); + AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi); + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Sdi, null); + AddInCardHdmiAndAudioLoopPorts(number); + } + else if (type == "dmcdvi") + { + new DmcDvi(number, Chassis); + AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvga") + { + new DmcVga(number, Chassis); + AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvidbnc") + { + new DmcVidBnc(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvidrcaa") + { + new DmcVidRcaA(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvidrcad") + { + new DmcVidRcaD(number, Chassis); + AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component); + AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcvid4") + { + new DmcVid4(number, Chassis); + AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite); + AddInCardHdmiLoopPort(number); + } + else if (type == "dmcstr") + { + new DmcStr(number, Chassis); + AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); + AddInCardHdmiAndAudioLoopPorts(number); + } + } + + void AddDmInCardPorts(uint number) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddDmInCardPorts(uint number, ICec cecPort) + { + AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddHdmiInCardPorts(uint number, ICec cecPort) + { + AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); + AddInCardHdmiAndAudioLoopPorts(number); + } + + void AddInCardHdmiAndAudioLoopPorts(uint number) + { + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null); + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "audioLoopOut", eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null); + } + + void AddInCardHdmiLoopPort(uint number) + { + AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null); + } + + /// + /// + /// + /// + /// + public void AddOutputCard(string type, uint number) + { + type = type.ToLower(); + + Debug.Console(2, this, "Adding output card '{0}', slot {1}", type, number); + if (type == "dmc4khdo") + { + var outputCard = new Dmc4kHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + else if (type == "dmchdo") + { + var outputCard = new DmcHdoSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + var cecPort2 = outputCard.Card2.HdmiOutput; + AddDmcHdoPorts(number, cecPort1, cecPort2); + } + else if (type == "dmc4kcohd") + { + var outputCard = new Dmc4kCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmc4kzcohd") + { + var outputCard = new Dmc4kzCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmccohd") + { + var outputCard = new DmcCoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmccatohd") + { + var outputCard = new DmcCatoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddDmcCoPorts(number, cecPort1); + } + else if (type == "dmcsohd") + { + var outputCard = new DmcSoHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmMmFiber, 2 * (number - 1) + 2); + } + else if (type == "dmcs2ohd") + { + var outputCard = new DmcS2oHdSingle(number, Chassis); + var cecPort1 = outputCard.Card1.HdmiOutput; + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmSmFiber, 2 * (number - 1) + 2); + } + else if (type == "dmcstro") + { + var outputCard = new DmcStroSingle(number, Chassis); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "streamOut", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Streaming, 2 * (number - 1) + 1); + } + + else + Debug.Console(1, this, " WARNING: Output card type '{0}' is not available", type); + } + + void AddDmcHdoPorts(uint number, ICec cecPort1, ICec cecPort2) + { + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut1", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, + 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 2, cecPort2); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "audioOut2", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, + 2 * (number - 1) + 2); + } + + void AddDmcCoPorts(uint number, ICec cecPort1) + { + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "hdmiOut1", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, 2 * (number - 1) + 1, cecPort1); + AddOutputPortWithDebug(string.Format("outputCard{0}", number), "dmOut2", eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.DmCat, 2 * (number - 1) + 2); + } + + /// + /// Adds InputPort + /// + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) + { + var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); + Debug.Console(2, this, "Adding input port '{0}'", portKey); + var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); + + InputPorts.Add(inputPort); + } + + /// + /// Adds InputPort and sets Port as ICec object + /// + void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) + { + var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); + Debug.Console(2, this, "Adding input port '{0}'", portKey); + var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); + + if (cecPort != null) + inputPort.Port = cecPort; + + InputPorts.Add(inputPort); + } + + /// + /// Adds OutputPort + /// + void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) + { + var portKey = string.Format("{0}--{1}", cardName, portName); + Debug.Console(2, this, "Adding output port '{0}'", portKey); + OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)); + } + + /// + /// Adds OutputPort and sets Port as ICec object + /// + void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) + { + var portKey = string.Format("{0}--{1}", cardName, portName); + Debug.Console(2, this, "Adding output port '{0}'", portKey); + var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); + + if (cecPort != null) + outputPort.Port = cecPort; + + OutputPorts.Add(outputPort); + } + + /// + /// + /// + void AddVolumeControl(uint number, Audio.Output audio) + { + VolumeControls.Add(number, new DmCardAudioOutputController(audio)); + } + + //public void SetInputHdcpSupport(uint input, ePdtHdcpSupport hdcpSetting) + //{ + + //} + + void Chassis_DMSystemChange(Switch device, DMSystemEventArgs args) + { + switch (args.EventId) + { + case DMSystemEventIds.SystemIdEventId: + { + Debug.Console(2, this, "SystemIdEvent Value: {0}", (Chassis as DmMDMnxn).SystemIdFeedback.UShortValue); + SystemIdFeebdack.FireUpdate(); + break; + } + case DMSystemEventIds.SystemIdBusyEventId: + { + Debug.Console(2, this, "SystemIdBusyEvent State: {0}", (Chassis as DmMDMnxn).SystemIdBusy.BoolValue); + SystemIdBusyFeedback.FireUpdate(); + break; + } + } + } + + void Chassis_DMInputChange(Switch device, DMInputEventArgs args) + { + switch (args.EventId) + { + case DMInputEventIds.EndpointOnlineEventId: + { + Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.OnlineFeedbackEventId: + { + Debug.Console(2, this, "DM Input OnlineFeedbackEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback); + InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.VideoDetectedEventId: + { + Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); + VideoInputSyncFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.InputNameEventId: + { + Debug.Console(2, this, "DM Input {0} NameFeedbackEventId", args.Number); + InputNameFeedbacks[args.Number].FireUpdate(); + break; + } + case DMInputEventIds.UsbRoutedToEventId: + { + Debug.Console(2, this, "DM Input {0} UsbRoutedToEventId", args.Number); + if (UsbInputRoutedToFeebacks[args.Number] != null) + UsbInputRoutedToFeebacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in UsbInputRoutedToFeedbacks"); + break; + } + case DMInputEventIds.HdcpCapabilityFeedbackEventId: + { + Debug.Console(2, this, "DM Input {0} HdcpCapabilityFeedbackEventId", args.Number); + if (InputCardHdcpCapabilityFeedbacks[args.Number] != null) + InputCardHdcpCapabilityFeedbacks[args.Number].FireUpdate(); + else + Debug.Console(1, this, "No index of {0} found in InputCardHdcpCapabilityFeedbacks"); + break; + } + default: + { + Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId); + break; + } + } + } + + /// + /// + void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) + { + var output = args.Number; + + switch (args.EventId) + { + case DMOutputEventIds.VolumeEventId: + { + if (VolumeControls.ContainsKey(output)) + { + VolumeControls[args.Number].VolumeEventFromChassis(); + } + + break; + } + case DMOutputEventIds.EndpointOnlineEventId: + { + Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. State: {1}", args.Number, + Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.OnlineFeedbackEventId: + { + Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, + Chassis.Outputs[output].EndpointOnlineFeedback); + OutputEndpointOnlineFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.VideoOutEventId: + { + if (Chassis.Outputs[output].VideoOutFeedback != null) + Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].VideoOutFeedback.Number, output); + + if (VideoOutputFeedbacks.ContainsKey(output)) + VideoOutputFeedbacks[output].FireUpdate(); + + if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) + OutputVideoRouteNameFeedbacks[output].FireUpdate(); + + break; + } + case DMOutputEventIds.AudioOutEventId: + { + if (Chassis.Outputs[output].AudioOutFeedback != null) + Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].AudioOutFeedback.Number, output); + + if (AudioOutputFeedbacks.ContainsKey(output)) + AudioOutputFeedbacks[output].FireUpdate(); + + if (OutputAudioRouteNameFeedbacks.ContainsKey(output)) + OutputAudioRouteNameFeedbacks[output].FireUpdate(); + + break; + } + case DMOutputEventIds.OutputNameEventId: + { + Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); + OutputNameFeedbacks[output].FireUpdate(); + break; + } + case DMOutputEventIds.UsbRoutedToEventId: + { + Debug.Console(2, this, "DM Output {0} UsbRoutedToEventId", args.Number); + UsbOutputRoutedToFeebacks[args.Number].FireUpdate(); + break; + } + case DMOutputEventIds.DisabledByHdcpEventId: + { + Debug.Console(2, this, "DM Output {0} DisabledByHdcpEventId", args.Number); + OutputDisabledByHdcpFeedbacks[args.Number].FireUpdate(); + break; + } + default: + { + Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId); + break; + } + } + } + + /// + /// + /// + /// + void StartOffTimer(PortNumberType pnt) + { + if (RouteOffTimers.ContainsKey(pnt)) + return; + RouteOffTimers[pnt] = new CTimer(o => { ExecuteSwitch(0, pnt.Number, pnt.Type); }, RouteOffTime); + } + + // Send out sigs when coming online + void IsOnline_OutputChange(object sender, EventArgs e) + { + if (IsOnline.BoolValue) + { + (Chassis as DmMDMnxn).EnableAudioBreakaway.BoolValue = true; + (Chassis as DmMDMnxn).EnableUSBBreakaway.BoolValue = true; + + if (InputNames != null) + foreach (var kvp in InputNames) + Chassis.Inputs[kvp.Key].Name.StringValue = kvp.Value; + if (OutputNames != null) + foreach (var kvp in OutputNames) + Chassis.Outputs[kvp.Key].Name.StringValue = kvp.Value; + } + } + + #region IRouting Members + public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType) + { + Debug.Console(2, this, "Making an awesome DM route from {0} to {1} {2}", inputSelector, outputSelector, sigType); + + var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail + var output = Convert.ToUInt32(outputSelector); + + // Check to see if there's an off timer waiting on this and if so, cancel + var key = new PortNumberType(output, sigType); + if (input == 0) + { + StartOffTimer(key); + } + else + { + if (RouteOffTimers.ContainsKey(key)) + { + Debug.Console(2, this, "{0} cancelling route off due to new source", output); + RouteOffTimers[key].Stop(); + RouteOffTimers.Remove(key); + } + } + + var inCard = input == 0 ? null : Chassis.Inputs[input]; + var outCard = input == 0 ? null : Chassis.Outputs[output]; + + // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES + if ((sigType | eRoutingSignalType.Video) == eRoutingSignalType.Video) + { + Chassis.VideoEnter.BoolValue = true; + Chassis.Outputs[output].VideoOut = inCard; + } + + if ((sigType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio) + { + (Chassis as DmMDMnxn).AudioEnter.BoolValue = true; + Chassis.Outputs[output].AudioOut = inCard; + } + + if ((sigType | eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) + { + Chassis.USBEnter.BoolValue = true; + if (Chassis.Outputs[output] != null) + Chassis.Outputs[output].USBRoutedTo = inCard; + } + + if ((sigType | eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) + { + Chassis.USBEnter.BoolValue = true; + if (Chassis.Inputs[input] != null) + Chassis.Inputs[input].USBRoutedTo = outCard; + } + } + #endregion + } + + public struct PortNumberType + { + public uint Number { get; private set; } + public eRoutingSignalType Type { get; private set; } + + public PortNumberType(uint number, eRoutingSignalType type) + : this() + { + Number = number; + Type = type; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs index d3fda242..2417ce7e 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs +++ b/essentials-framework/Essentials DM/Essentials_DM/Config/DeviceFactory.cs @@ -30,14 +30,17 @@ namespace PepperDash.Essentials.DM if (typeName.StartsWith("am")) { - var props = JsonConvert.DeserializeObject(properties.ToString()); - AmX00 amDevice = null; - if (typeName == "am200") - amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am200(props.Control.IpIdInt, Global.ControlSystem); - else if(typeName == "am300") - amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am300(props.Control.IpIdInt, Global.ControlSystem); + if (typeName == "am200" || typeName == "am300") + { + var props = JsonConvert.DeserializeObject(properties.ToString()); + AmX00 amDevice = null; + if (typeName == "am200") + amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am200(props.Control.IpIdInt, Global.ControlSystem); + else if (typeName == "am300") + amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am300(props.Control.IpIdInt, Global.ControlSystem); - return new AirMediaController(key, name, amDevice, dc, props); + return new AirMediaController(key, name, amDevice, dc, props); + } } else if (typeName.StartsWith("dmmd8x") || typeName.StartsWith("dmmd16x") || typeName.StartsWith("dmmd32x")) { diff --git a/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj b/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj index e862f8a1..94154d6c 100644 --- a/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj +++ b/essentials-framework/Essentials DM/Essentials_DM/Essentials_DM.csproj @@ -84,7 +84,7 @@ False - ..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs index a735d9a8..380a090a 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOccupancySensorBaseController.cs @@ -103,6 +103,18 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy PirSensitivityInOccupiedStateFeedback.FireUpdate(); else if (args.EventId == GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId) PirSensitivityInVacantStateFeedback.FireUpdate(); + } + + protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) + { + Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId); + + if (args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId + || args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId) + { + Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); + RoomIsOccupiedFeedback.FireUpdate(); + } else if (args.EventId == GlsOccupancySensorBase.TimeoutFeedbackEventId) CurrentTimeoutFeedback.FireUpdate(); else if (args.EventId == GlsOccupancySensorBase.TimeoutLocalFeedbackEventId) @@ -117,18 +129,6 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy ExternalPhotoSensorValue.FireUpdate(); } - void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) - { - Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId); - - if (args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId - || args.EventId == Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId) - { - Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue); - RoomIsOccupiedFeedback.FireUpdate(); - } - } - public void SetTestMode(bool mode) { InTestMode = mode; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs index 7f034fbe..16e449bf 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Occupancy/GlsOdtOccupancySensorController.cs @@ -1,65 +1,65 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.GeneralIO; - -using PepperDash.Core; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials.Devices.Common.Occupancy -{ - public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController - { - public new GlsOdtCCn OccSensor { get; private set; } - - public BoolFeedback OrWhenVacatedFeedback { get; private set; } - - public BoolFeedback AndWhenVacatedFeedback { get; private set; } - - public BoolFeedback UltrasonicAEnabledFeedback { get; private set; } - - public BoolFeedback UltrasonicBEnabledFeedback { get; private set; } - - public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; } - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.GeneralIO; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials.Devices.Common.Occupancy +{ + public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController + { + public new GlsOdtCCn OccSensor { get; private set; } + + public BoolFeedback OrWhenVacatedFeedback { get; private set; } + + public BoolFeedback AndWhenVacatedFeedback { get; private set; } + + public BoolFeedback UltrasonicAEnabledFeedback { get; private set; } + + public BoolFeedback UltrasonicBEnabledFeedback { get; private set; } + + public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; } + public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; } public BoolFeedback RawOccupancyPirFeedback { get; private set; } - public BoolFeedback RawOccupancyUsFeedback { get; private set; } - - - public GlsOdtOccupancySensorController(string key, string name, GlsOdtCCn sensor) - : base(key, name, sensor) - { - OccSensor = sensor; - - AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); - - OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); - - UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); - + public BoolFeedback RawOccupancyUsFeedback { get; private set; } + + + public GlsOdtOccupancySensorController(string key, string name, GlsOdtCCn sensor) + : base(key, name, sensor) + { + OccSensor = sensor; + + AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue); + + OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue); + + UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue); + UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue); RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue); - RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); - - UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); - + RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue); + + UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue); + UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue); - } - - /// - /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. - /// Then calls the base delegate method to ensure any common event IDs are captured. - /// - /// - /// - protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) + } + + /// + /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. + /// Then calls the base delegate method to ensure any common event IDs are captured. + /// + /// + /// + protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args) { if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId) AndWhenVacatedFeedback.FireUpdate(); @@ -69,91 +69,103 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy UltrasonicAEnabledFeedback.FireUpdate(); else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId) UltrasonicBEnabledFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) - RawOccupancyPirFeedback.FireUpdate(); - else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) - RawOccupancyUsFeedback.FireUpdate(); else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId) UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate(); else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId) UltrasonicSensitivityInVacantStateFeedback.FireUpdate(); - - base.OccSensor_GlsOccupancySensorChange(device, args); - } - - /// - /// Sets the OrWhenVacated state - /// - /// - public void SetOrWhenVacatedState(bool state) - { - OccSensor.OrWhenVacated.BoolValue = state; - } - - /// - /// Sets the AndWhenVacated state - /// - /// - public void SetAndWhenVacatedState(bool state) - { - OccSensor.AndWhenVacated.BoolValue = state; - } - - /// - /// Enables or disables the Ultrasonic A sensor - /// - /// - public void SetUsAEnable(bool state) - { - if (state) - { - OccSensor.EnableUsA.BoolValue = state; - OccSensor.DisableUsA.BoolValue = !state; - } - else - { - OccSensor.EnableUsA.BoolValue = state; - OccSensor.DisableUsA.BoolValue = !state; - } - } - - - /// - /// Enables or disables the Ultrasonic B sensor - /// - /// - public void SetUsBEnable(bool state) - { - if (state) - { - OccSensor.EnableUsB.BoolValue = state; - OccSensor.DisableUsB.BoolValue = !state; - } - else - { - OccSensor.EnableUsB.BoolValue = state; - OccSensor.DisableUsB.BoolValue = !state; - } - } - - public void IncrementUsSensitivityInOccupiedState(bool pressRelease) - { - OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease; - } - - public void DecrementUsSensitivityInOccupiedState(bool pressRelease) - { - OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease; - } - - public void IncrementUsSensitivityInVacantState(bool pressRelease) - { - OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease; - } - - public void DecrementUsSensitivityInVacantState(bool pressRelease) - { - OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; - } - } + + base.OccSensor_GlsOccupancySensorChange(device, args); + } + + /// + /// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class. + /// Then calls the base delegate method to ensure any common event IDs are captured. + /// + /// + /// + protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args) + { + if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId) + RawOccupancyPirFeedback.FireUpdate(); + else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId) + RawOccupancyUsFeedback.FireUpdate(); + + base.OccSensor_BaseEvent(device, args); + } + + /// + /// Sets the OrWhenVacated state + /// + /// + public void SetOrWhenVacatedState(bool state) + { + OccSensor.OrWhenVacated.BoolValue = state; + } + + /// + /// Sets the AndWhenVacated state + /// + /// + public void SetAndWhenVacatedState(bool state) + { + OccSensor.AndWhenVacated.BoolValue = state; + } + + /// + /// Enables or disables the Ultrasonic A sensor + /// + /// + public void SetUsAEnable(bool state) + { + if (state) + { + OccSensor.EnableUsA.BoolValue = state; + OccSensor.DisableUsA.BoolValue = !state; + } + else + { + OccSensor.EnableUsA.BoolValue = state; + OccSensor.DisableUsA.BoolValue = !state; + } + } + + + /// + /// Enables or disables the Ultrasonic B sensor + /// + /// + public void SetUsBEnable(bool state) + { + if (state) + { + OccSensor.EnableUsB.BoolValue = state; + OccSensor.DisableUsB.BoolValue = !state; + } + else + { + OccSensor.EnableUsB.BoolValue = state; + OccSensor.DisableUsB.BoolValue = !state; + } + } + + public void IncrementUsSensitivityInOccupiedState(bool pressRelease) + { + OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease; + } + + public void DecrementUsSensitivityInOccupiedState(bool pressRelease) + { + OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease; + } + + public void IncrementUsSensitivityInVacantState(bool pressRelease) + { + OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease; + } + + public void DecrementUsSensitivityInVacantState(bool pressRelease) + { + OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease; + } + } } \ No newline at end of file diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs index 5af965fe..78e2ac22 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SetTopBox/IRSetTopBoxBase.cs @@ -1,343 +1,371 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Presets; -using PepperDash.Essentials.Core.Routing; - -namespace PepperDash.Essentials.Devices.Common -{ - public class IRSetTopBoxBase : Device, ISetTopBoxControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking - { - public IrOutputPortController IrPort { get; private set; } - - public uint DisplayUiType { get { return DisplayUiConstants.TypeDirecTv; } } - - - public bool HasPresets { get; set; } - public bool HasDvr { get; set; } - public bool HasDpad { get; set; } - public bool HasNumeric { get; set; } - - public DevicePresetsModel PresetsModel { get; private set; } - - public IRSetTopBoxBase(string key, string name, IrOutputPortController portCont, - SetTopBoxPropertiesConfig props) - : base(key, name) - { - IrPort = portCont; - DeviceManager.AddDevice(portCont); - - HasPresets = props.HasPresets; - HasDvr = props.HasDvr; - HasDpad = props.HasDpad; - HasNumeric = props.HasNumeric; - - HasKeypadAccessoryButton1 = true; - KeypadAccessoryButton1Command = "Dash"; - KeypadAccessoryButton1Label = "-"; - - HasKeypadAccessoryButton2 = true; - KeypadAccessoryButton2Command = "NumericEnter"; - KeypadAccessoryButton2Label = "Enter"; - - AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, - eRoutingPortConnectionType.Hdmi, null, this); - AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, - eRoutingPortConnectionType.DigitalAudio, null, this); - OutputPorts = new RoutingPortCollection { AnyVideoOut, AnyAudioOut }; - - } - - public void LoadPresets(string filePath) - { - PresetsModel = new DevicePresetsModel(Key + "-presets", this, filePath); - DeviceManager.AddDevice(PresetsModel); - } - - - #region ISetTopBoxControls Members - - public void DvrList(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_DVR, pressRelease); - } - - public void Replay(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); - } - - #endregion - - #region IDPad Members - - public void Up(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease); - } - - public void Down(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease); - } - - public void Left(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease); - } - - public void Right(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease); - } - - public void Select(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease); - } - - public void Menu(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease); - } - - public void Exit(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease); - } - - #endregion - - #region INumericKeypad Members - - public void Digit0(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_0, pressRelease); - } - - public void Digit1(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_1, pressRelease); - } - - public void Digit2(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_2, pressRelease); - } - - public void Digit3(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_3, pressRelease); - } - - public void Digit4(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_4, pressRelease); - } - - public void Digit5(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_5, pressRelease); - } - - public void Digit6(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_6, pressRelease); - } - - public void Digit7(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_7, pressRelease); - } - - public void Digit8(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_8, pressRelease); - } - - public void Digit9(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_9, pressRelease); - } - - /// - /// Defaults to true - /// - public bool HasKeypadAccessoryButton1 { get; set; } - - /// - /// Defaults to "-" - /// - public string KeypadAccessoryButton1Label { get; set; } - - - /// - /// Defaults to "Dash" - /// - public string KeypadAccessoryButton1Command { get; set; } - - public void KeypadAccessoryButton1(bool pressRelease) - { - IrPort.PressRelease(KeypadAccessoryButton1Command, pressRelease); - } - - /// - /// Defaults to true - /// - public bool HasKeypadAccessoryButton2 { get; set; } - - /// - /// Defaults to "Enter" - /// - public string KeypadAccessoryButton2Label { get; set; } - - - /// - /// Defaults to "Enter" - /// - public string KeypadAccessoryButton2Command { get; set; } - - public void KeypadAccessoryButton2(bool pressRelease) - { - IrPort.PressRelease(KeypadAccessoryButton2Command, pressRelease); - } - - #endregion - - #region ISetTopBoxNumericKeypad Members - - /// - /// Corresponds to "dash" IR command - /// - public void Dash(bool pressRelease) - { - IrPort.PressRelease("dash", pressRelease); - } - - /// - /// Corresponds to "numericEnter" IR command - /// - public void KeypadEnter(bool pressRelease) - { - IrPort.PressRelease("numericEnter", pressRelease); - } - - #endregion - - #region IChannelFunctions Members - - public void ChannelUp(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_CH_PLUS, pressRelease); - } - - public void ChannelDown(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_CH_MINUS, pressRelease); - } - - public void LastChannel(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_LAST, pressRelease); - } - - public void Guide(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_GUIDE, pressRelease); - } - - public void Info(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_INFO, pressRelease); - } - - #endregion - - #region IColorFunctions Members - - public void Red(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RED, pressRelease); - } - - public void Green(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_GREEN, pressRelease); - } - - public void Yellow(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_YELLOW, pressRelease); - } - - public void Blue(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_BLUE, pressRelease); - } - - #endregion - - #region IRoutingOutputs Members - - public RoutingOutputPort AnyVideoOut { get; private set; } - public RoutingOutputPort AnyAudioOut { get; private set; } - public RoutingPortCollection OutputPorts { get; private set; } - - #endregion - - #region ITransport Members - - public void ChapMinus(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); - } - - public void ChapPlus(bool pressRelease) - { - } - - public void FFwd(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease); - } - - public void Pause(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); - } - - public void Play(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease); - } - - public void Record(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RECORD, pressRelease); - } - - public void Rewind(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); - } - - public void Stop(bool pressRelease) - { - IrPort.PressRelease(IROutputStandardCommands.IROut_STOP, pressRelease); - } - - #endregion - - #region IUsageTracking Members - - public UsageTracking UsageTracker { get; set; } - - #endregion - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Presets; +using PepperDash.Essentials.Core.Routing; + +namespace PepperDash.Essentials.Devices.Common +{ + public class IRSetTopBoxBase : Device, ISetTopBoxControls, IUiDisplayInfo, IRoutingOutputs, IUsageTracking, IPower + { + public IrOutputPortController IrPort { get; private set; } + + public uint DisplayUiType { get { return DisplayUiConstants.TypeDirecTv; } } + + + public bool HasPresets { get; set; } + public bool HasDvr { get; set; } + public bool HasDpad { get; set; } + public bool HasNumeric { get; set; } + + public DevicePresetsModel PresetsModel { get; private set; } + + public IRSetTopBoxBase(string key, string name, IrOutputPortController portCont, + SetTopBoxPropertiesConfig props) + : base(key, name) + { + IrPort = portCont; + DeviceManager.AddDevice(portCont); + + HasPresets = props.HasPresets; + HasDvr = props.HasDvr; + HasDpad = props.HasDpad; + HasNumeric = props.HasNumeric; + + HasKeypadAccessoryButton1 = true; + KeypadAccessoryButton1Command = "Dash"; + KeypadAccessoryButton1Label = "-"; + + HasKeypadAccessoryButton2 = true; + KeypadAccessoryButton2Command = "NumericEnter"; + KeypadAccessoryButton2Label = "Enter"; + + AnyVideoOut = new RoutingOutputPort(RoutingPortNames.AnyVideoOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, + eRoutingPortConnectionType.Hdmi, null, this); + AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, + eRoutingPortConnectionType.DigitalAudio, null, this); + OutputPorts = new RoutingPortCollection { AnyVideoOut, AnyAudioOut }; + + } + + public void LoadPresets(string filePath) + { + PresetsModel = new DevicePresetsModel(Key + "-presets", this, filePath); + DeviceManager.AddDevice(PresetsModel); + } + + + #region ISetTopBoxControls Members + + public void DvrList(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_DVR, pressRelease); + } + + public void Replay(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); + } + + #endregion + + #region IDPad Members + + public void Up(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_UP_ARROW, pressRelease); + } + + public void Down(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_DN_ARROW, pressRelease); + } + + public void Left(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_LEFT_ARROW, pressRelease); + } + + public void Right(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RIGHT_ARROW, pressRelease); + } + + public void Select(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_ENTER, pressRelease); + } + + public void Menu(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_MENU, pressRelease); + } + + public void Exit(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_EXIT, pressRelease); + } + + #endregion + + #region INumericKeypad Members + + public void Digit0(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_0, pressRelease); + } + + public void Digit1(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_1, pressRelease); + } + + public void Digit2(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_2, pressRelease); + } + + public void Digit3(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_3, pressRelease); + } + + public void Digit4(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_4, pressRelease); + } + + public void Digit5(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_5, pressRelease); + } + + public void Digit6(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_6, pressRelease); + } + + public void Digit7(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_7, pressRelease); + } + + public void Digit8(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_8, pressRelease); + } + + public void Digit9(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_9, pressRelease); + } + + /// + /// Defaults to true + /// + public bool HasKeypadAccessoryButton1 { get; set; } + + /// + /// Defaults to "-" + /// + public string KeypadAccessoryButton1Label { get; set; } + + + /// + /// Defaults to "Dash" + /// + public string KeypadAccessoryButton1Command { get; set; } + + public void KeypadAccessoryButton1(bool pressRelease) + { + IrPort.PressRelease(KeypadAccessoryButton1Command, pressRelease); + } + + /// + /// Defaults to true + /// + public bool HasKeypadAccessoryButton2 { get; set; } + + /// + /// Defaults to "Enter" + /// + public string KeypadAccessoryButton2Label { get; set; } + + + /// + /// Defaults to "Enter" + /// + public string KeypadAccessoryButton2Command { get; set; } + + public void KeypadAccessoryButton2(bool pressRelease) + { + IrPort.PressRelease(KeypadAccessoryButton2Command, pressRelease); + } + + #endregion + + #region ISetTopBoxNumericKeypad Members + + /// + /// Corresponds to "dash" IR command + /// + public void Dash(bool pressRelease) + { + IrPort.PressRelease("dash", pressRelease); + } + + /// + /// Corresponds to "numericEnter" IR command + /// + public void KeypadEnter(bool pressRelease) + { + IrPort.PressRelease("numericEnter", pressRelease); + } + + #endregion + + #region IChannelFunctions Members + + public void ChannelUp(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_CH_PLUS, pressRelease); + } + + public void ChannelDown(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_CH_MINUS, pressRelease); + } + + public void LastChannel(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_LAST, pressRelease); + } + + public void Guide(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_GUIDE, pressRelease); + } + + public void Info(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_INFO, pressRelease); + } + + #endregion + + #region IColorFunctions Members + + public void Red(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RED, pressRelease); + } + + public void Green(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_GREEN, pressRelease); + } + + public void Yellow(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_YELLOW, pressRelease); + } + + public void Blue(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_BLUE, pressRelease); + } + + #endregion + + #region IRoutingOutputs Members + + public RoutingOutputPort AnyVideoOut { get; private set; } + public RoutingOutputPort AnyAudioOut { get; private set; } + public RoutingPortCollection OutputPorts { get; private set; } + + #endregion + + #region ITransport Members + + public void ChapMinus(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_REPLAY, pressRelease); + } + + public void ChapPlus(bool pressRelease) + { + } + + public void FFwd(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_FSCAN, pressRelease); + } + + public void Pause(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); + } + + public void Play(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_PLAY, pressRelease); + } + + public void Record(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RECORD, pressRelease); + } + + public void Rewind(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_RSCAN, pressRelease); + } + + public void Stop(bool pressRelease) + { + IrPort.PressRelease(IROutputStandardCommands.IROut_STOP, pressRelease); + } + + #endregion + + #region IUsageTracking Members + + public UsageTracking UsageTracker { get; set; } + + #endregion + + #region IPower Members + + public void PowerOn() + { + IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_ON, true); + IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_ON, false); + + } + + public void PowerOff() + { + IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_OFF, true); + IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_OFF, false); + + } + + public void PowerToggle() + { + throw new NotImplementedException(); + } + + public BoolFeedback PowerIsOnFeedback + { + get { throw new NotImplementedException(); } + } + + #endregion + } } \ No newline at end of file