mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-21 00:14:55 +00:00
Compare commits
340 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3383db890 | ||
|
|
139e5370ea | ||
|
|
bdd17dfa27 | ||
|
|
6443e00428 | ||
|
|
008279e867 | ||
|
|
c4a6d20791 | ||
|
|
61b4002e5a | ||
|
|
da63d0917e | ||
|
|
0228fd1c0f | ||
|
|
085ba134c4 | ||
|
|
a9fce3237c | ||
|
|
840fb21e15 | ||
|
|
8ed236abae | ||
|
|
4a9b1514e3 | ||
|
|
9c7e38b379 | ||
|
|
846e905ae1 | ||
|
|
31f6a4bcfd | ||
|
|
2da8f8c9a8 | ||
|
|
743accd980 | ||
|
|
b445f68466 | ||
|
|
847e106b8d | ||
|
|
57f2d7c938 | ||
|
|
f0415d0d05 | ||
|
|
07fbe102bd | ||
|
|
319909539c | ||
|
|
00589488ac | ||
|
|
f25219c20a | ||
|
|
c5aef18943 | ||
|
|
70d4a7054f | ||
|
|
b20009b247 | ||
|
|
9588564633 | ||
|
|
eef3b5fb31 | ||
|
|
7078ba55c7 | ||
|
|
e06be3ebe9 | ||
|
|
10046a9ed4 | ||
|
|
51f294c37f | ||
|
|
1990201215 | ||
|
|
be78d17af5 | ||
|
|
8a6d5ebd56 | ||
|
|
93c0b33958 | ||
|
|
dca21aa4dc | ||
|
|
ac09267173 | ||
|
|
ef63c1db02 | ||
|
|
f828cbecbd | ||
|
|
890abf4383 | ||
|
|
52c96cc2c3 | ||
|
|
4ab3cdb1ff | ||
|
|
2dfd647f63 | ||
|
|
7f054d5e98 | ||
|
|
43297c0341 | ||
|
|
6280aa90c9 | ||
|
|
ca497c8f47 | ||
|
|
1da481a8db | ||
|
|
c04d79931d | ||
|
|
dbd3ab2f70 | ||
|
|
36b5faa3d9 | ||
|
|
07bf74ab19 | ||
|
|
e356f57e1a | ||
|
|
86ad88969e | ||
|
|
7020480159 | ||
|
|
bc54856392 | ||
|
|
24a435c965 | ||
|
|
2897ec1d83 | ||
|
|
f075412a86 | ||
|
|
4f5bb4dc46 | ||
|
|
382c35924c | ||
|
|
88c332729f | ||
|
|
e9a6aa641b | ||
|
|
16bc2ca381 | ||
|
|
2fc1f45161 | ||
|
|
ef7eae50e4 | ||
|
|
2c50efd4c5 | ||
|
|
3ebe44be34 | ||
|
|
e7b322c303 | ||
|
|
08491bdf2a | ||
|
|
f1fa3c07fd | ||
|
|
b19b4ae26e | ||
|
|
7f8215199d | ||
|
|
dd060c4442 | ||
|
|
e782339dcc | ||
|
|
766ed3ab51 | ||
|
|
cd0e3f7001 | ||
|
|
29d5ecb13f | ||
|
|
2987f600bb | ||
|
|
5c23aeca48 | ||
|
|
6ef8ba3639 | ||
|
|
4f7ad4ccb9 | ||
|
|
e03b0dc1bb | ||
|
|
b75153b848 | ||
|
|
d70d33c5e3 | ||
|
|
7eb6748682 | ||
|
|
c92c750e55 | ||
|
|
225c6281b9 | ||
|
|
249e9f372e | ||
|
|
4dfab9a287 | ||
|
|
ec43749ba4 | ||
|
|
2e4202ccce | ||
|
|
4c16dd07b5 | ||
|
|
0c4ad1c4df | ||
|
|
eb90fb343d | ||
|
|
2967a0f968 | ||
|
|
7b2a8b17b7 | ||
|
|
89ca614d3d | ||
|
|
355df1341e | ||
|
|
78c17cd729 | ||
|
|
504c21204f | ||
|
|
8dba5a335b | ||
|
|
3d6d578663 | ||
|
|
a5e9d7ba55 | ||
|
|
5eb65fd723 | ||
|
|
e0dcde5c35 | ||
|
|
c6cfecdbbb | ||
|
|
30bdac93ee | ||
|
|
1228431bc2 | ||
|
|
5a2070de3f | ||
|
|
bc1645065c | ||
|
|
21f9795bcd | ||
|
|
a69bc94945 | ||
|
|
864c8ddf77 | ||
|
|
5764149306 | ||
|
|
9abd911a95 | ||
|
|
968f85b04e | ||
|
|
6e09ef35ab | ||
|
|
a36bce4d5e | ||
|
|
5374e58197 | ||
|
|
cbfa7d869b | ||
|
|
434fb1be59 | ||
|
|
dbec078dae | ||
|
|
e9a8e42525 | ||
|
|
8ad7b429a2 | ||
|
|
a1c27d64ad | ||
|
|
4814d0f769 | ||
|
|
b7d7196071 | ||
|
|
d8225a80b6 | ||
|
|
1b0d9ae904 | ||
|
|
7228733aad | ||
|
|
809639c3f9 | ||
|
|
24e59e1474 | ||
|
|
42c483f581 | ||
|
|
7ba0ecdf5c | ||
|
|
ece36b4042 | ||
|
|
ca5b35b39c | ||
|
|
8f804766e5 | ||
|
|
00207d1570 | ||
|
|
65747b6ad2 | ||
|
|
f7174e2492 | ||
|
|
5d7cdab933 | ||
|
|
c9fee785f9 | ||
|
|
dfc90e58dc | ||
|
|
2a5810b671 | ||
|
|
9d354fb0ed | ||
|
|
52494ca13e | ||
|
|
55cbd094be | ||
|
|
da5fd7e743 | ||
|
|
f6059e249f | ||
|
|
8545622c79 | ||
|
|
cf14706961 | ||
|
|
2f172c998a | ||
|
|
7945bce854 | ||
|
|
6d66c5adee | ||
|
|
8ccbed6d81 | ||
|
|
c3c58e3201 | ||
|
|
f547eb3a09 | ||
|
|
44cacc839b | ||
|
|
6dbe1b6f31 | ||
|
|
e15ed3c77f | ||
|
|
435879e19b | ||
|
|
17ccaecf5e | ||
|
|
dfebd47ef4 | ||
|
|
684b8db546 | ||
|
|
3c714f724d | ||
|
|
03e0dc5208 | ||
|
|
14991bce95 | ||
|
|
50b2c7d3af | ||
|
|
030d69c190 | ||
|
|
08fe408dc1 | ||
|
|
bdb007f6ed | ||
|
|
91abe4c09a | ||
|
|
82029894e4 | ||
|
|
3c1ed6e58a | ||
|
|
8999097100 | ||
|
|
72197e547f | ||
|
|
9b62849d9d | ||
|
|
d311b6fef9 | ||
|
|
4a642b1e36 | ||
|
|
de4f003c67 | ||
|
|
708ee1a8ff | ||
|
|
7196d0aba8 | ||
|
|
3b0a5285ab | ||
|
|
ae03b8cd7e | ||
|
|
cc159e306e | ||
|
|
0a43f43f66 | ||
|
|
0f924360c1 | ||
|
|
0a34f48e0a | ||
|
|
870f2f8fa6 | ||
|
|
aa61479adc | ||
|
|
522c107ce6 | ||
|
|
cb29775004 | ||
|
|
fccbb55344 | ||
|
|
b2402402d9 | ||
|
|
f0a3b27e3b | ||
|
|
57ebd2b608 | ||
|
|
695ff5487f | ||
|
|
66cd39c013 | ||
|
|
fc91ba7c1e | ||
|
|
1cad1976ee | ||
|
|
91eec8c258 | ||
|
|
d2c308c009 | ||
|
|
a4a99f4a9b | ||
|
|
eb114b4a95 | ||
|
|
93e8d50e55 | ||
|
|
3c6fc978d4 | ||
|
|
01ddf1721c | ||
|
|
1ee87c0499 | ||
|
|
f8ae6264f7 | ||
|
|
3e56859943 | ||
|
|
945db8a233 | ||
|
|
823f7447c3 | ||
|
|
6e4fa48b9d | ||
|
|
7e8f216afb | ||
|
|
b09c151738 | ||
|
|
56cf54a644 | ||
|
|
169e897748 | ||
|
|
748b1ca147 | ||
|
|
2e636082bb | ||
|
|
9204ad2701 | ||
|
|
8feb7a142c | ||
|
|
d990930b19 | ||
|
|
4d67279827 | ||
|
|
a78b29b0a1 | ||
|
|
2c36c0f2cb | ||
|
|
2eaf21b1e0 | ||
|
|
099e387570 | ||
|
|
c4755f23cd | ||
|
|
9c4650b4af | ||
|
|
43d7fab04d | ||
|
|
d2b7e71c4a | ||
|
|
ab6d44e604 | ||
|
|
0dc2e9d134 | ||
|
|
3a024b8d4c | ||
|
|
05e2422cb4 | ||
|
|
fc5d4f946d | ||
|
|
45c1e25e4f | ||
|
|
f11bdcfd53 | ||
|
|
9888fbf047 | ||
|
|
9171610e34 | ||
|
|
7a8c1f3165 | ||
|
|
008a052045 | ||
|
|
93a5f2e3b2 | ||
|
|
0e4edca08a | ||
|
|
f9925f9ec9 | ||
|
|
f283f82bbc | ||
|
|
ab5dd5f756 | ||
|
|
e22c71853f | ||
|
|
8bf27ecbd9 | ||
|
|
d94d003050 | ||
|
|
25c4d94366 | ||
|
|
91dda3213e | ||
|
|
b41dd23c7f | ||
|
|
14ad0eee48 | ||
|
|
56e106ff32 | ||
|
|
b67424c1e1 | ||
|
|
c366ee9d12 | ||
|
|
5ec97f2e31 | ||
|
|
98c20464d7 | ||
|
|
b1aa9c3306 | ||
|
|
db6ab3ee98 | ||
|
|
2ccf4be559 | ||
|
|
ce86255119 | ||
|
|
d69e81972e | ||
|
|
3f9d306a34 | ||
|
|
14c3914e5c | ||
|
|
b5337572c4 | ||
|
|
1d1b4f0790 | ||
|
|
ccdd8005d0 | ||
|
|
1d184f0f5e | ||
|
|
2ed9e632c6 | ||
|
|
ecba28c9cd | ||
|
|
06e8cac597 | ||
|
|
1dfdd4dd28 | ||
|
|
48585469f6 | ||
|
|
f9ba562b0b | ||
|
|
5c63a49071 | ||
|
|
3d224496a8 | ||
|
|
73addfefe7 | ||
|
|
af0e2180bd | ||
|
|
a431015853 | ||
|
|
788244fbf4 | ||
|
|
282230b28e | ||
|
|
dc010ce28c | ||
|
|
5a3597f2a7 | ||
|
|
5b889ea59c | ||
|
|
faa6e20034 | ||
|
|
82a97f8c1f | ||
|
|
6557d21aa8 | ||
|
|
a733ed69cb | ||
|
|
9877ba93a0 | ||
|
|
669f9e71bc | ||
|
|
5d2f20efd5 | ||
|
|
06dccdd97f | ||
|
|
e705f67333 | ||
|
|
4903b99eb5 | ||
|
|
38ab6626fc | ||
|
|
b44bc8fae3 | ||
|
|
7d72d54862 | ||
|
|
0a218cebb4 | ||
|
|
ed6ad6ae76 | ||
|
|
1689b15d95 | ||
|
|
010fdde45c | ||
|
|
10509991c1 | ||
|
|
c686ee394d | ||
|
|
985902092e | ||
|
|
944b72e2a8 | ||
|
|
d074be323c | ||
|
|
0098401584 | ||
|
|
0d7d5fe380 | ||
|
|
1cb9fb6058 | ||
|
|
5076ba405e | ||
|
|
3c60dfdf7b | ||
|
|
5d44b5f3ef | ||
|
|
40cdd4c1e7 | ||
|
|
f5753109d5 | ||
|
|
51e338749a | ||
|
|
e37fb33afe | ||
|
|
47af06578a | ||
|
|
ad0cbba0b1 | ||
|
|
c7a3282dd9 | ||
|
|
fd593baa07 | ||
|
|
88f1230620 | ||
|
|
cad558980f | ||
|
|
e879aba801 | ||
|
|
114fdb9545 | ||
|
|
1886ddfbaf | ||
|
|
39d2c3aab6 | ||
|
|
3cd8a1f310 | ||
|
|
b457886ee3 | ||
|
|
e27c041256 | ||
|
|
5fcafe0b38 | ||
|
|
8250246f34 | ||
|
|
e573749aa0 |
170
.github/workflows/docker.yml
vendored
170
.github/workflows/docker.yml
vendored
@@ -32,7 +32,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
# Fetch all tags
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags
|
||||
@@ -41,12 +40,11 @@ jobs:
|
||||
shell: powershell
|
||||
run: |
|
||||
$version = ./.github/scripts/GenerateVersionNumber.ps1
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
# Use the version number to set the version of the assemblies
|
||||
- name: Update AssemblyInfo.cs
|
||||
shell: powershell
|
||||
run: |
|
||||
Write-Output ${{ env.VERSION }}
|
||||
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
|
||||
- name: restore Nuget Packages
|
||||
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
|
||||
@@ -80,16 +78,9 @@ jobs:
|
||||
with:
|
||||
name: Version
|
||||
path: ${{env.GITHUB_HOME}}\output\version.txt
|
||||
# Create the release on the source repo
|
||||
- name: Create tag for non-rc builds
|
||||
if: contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta')
|
||||
run: |
|
||||
git tag $($Env:VERSION)
|
||||
git push --tags origin
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
# using contributor's version to allow for pointing at the right commit
|
||||
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
|
||||
uses: fleskesvor/create-release@feature/support-target-commitish
|
||||
with:
|
||||
tag_name: ${{ env.VERSION }}
|
||||
@@ -123,7 +114,7 @@ jobs:
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
- name: Download Build output
|
||||
@@ -152,160 +143,3 @@ jobs:
|
||||
run: nuget push **/*.nupkg -source github
|
||||
- name: Publish nuget package to nuget.org
|
||||
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
|
||||
# This step always runs and pushes the build to the internal build rep
|
||||
Internal_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: check Github ref
|
||||
run: ${{toJson(github.ref)}}
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash-Engineering/essentials-builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Create new branch
|
||||
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: |
|
||||
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
|
||||
Write-Host "Branch: $branch"
|
||||
git push -u origin $($branch) --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
# This step only runs if the branch is main 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, 'main') || contains(github.ref, '/release/')
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: check Github ref
|
||||
run: ${{toJson(github.ref)}}
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash/Essentials-Builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Create new branch
|
||||
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: |
|
||||
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
|
||||
Write-Host "Branch: $branch"
|
||||
git push -u origin $($branch) --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
|
||||
160
.github/workflows/main.yml
vendored
160
.github/workflows/main.yml
vendored
@@ -24,25 +24,18 @@ jobs:
|
||||
# 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
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# 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)"
|
||||
run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
# Use the version number to set the version of the assemblies
|
||||
- name: Update AssemblyInfo.cs
|
||||
shell: powershell
|
||||
run: |
|
||||
Write-Output ${{ env.VERSION }}
|
||||
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
|
||||
- name: restore Nuget Packages
|
||||
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
|
||||
@@ -101,7 +94,7 @@ jobs:
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
- name: Download Build output
|
||||
@@ -130,148 +123,3 @@ jobs:
|
||||
run: nuget push **/*.nupkg -source github
|
||||
- name: Publish nuget package to nuget.org
|
||||
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
|
||||
Internal_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash-Engineering/essentials-builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Checkout main branch
|
||||
run: git checkout main
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin main --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 main or release/ runs and pushes the build to the public build repo
|
||||
Public_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash/Essentials-Builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout main branch
|
||||
- name: Create new branch
|
||||
run: git checkout main
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin main --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -388,3 +388,4 @@ MigrationBackup/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -70,6 +70,14 @@ namespace PepperDash.Essentials.Bridges
|
||||
/// Range reports the highest supported HDCP state level for the corresponding input card
|
||||
/// </summary>
|
||||
public uint HdcpSupportCapability { get; set; }
|
||||
/// <summary>
|
||||
/// DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback
|
||||
/// </summary>
|
||||
public uint InputStreamCardStatus { get; set; }
|
||||
/// <summary>
|
||||
/// DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback
|
||||
/// </summary>
|
||||
public uint OutputStreamCardStatus { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Serials
|
||||
@@ -115,6 +123,8 @@ namespace PepperDash.Essentials.Bridges
|
||||
InputUsb = 700; //701-899
|
||||
HdcpSupportState = 1000; //1001-1199
|
||||
HdcpSupportCapability = 1200; //1201-1399
|
||||
InputStreamCardStatus = 1500; //1501-1532
|
||||
OutputStreamCardStatus = 1600; //1601-1632
|
||||
|
||||
|
||||
//Serial
|
||||
@@ -145,6 +155,8 @@ namespace PepperDash.Essentials.Bridges
|
||||
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
|
||||
HdcpSupportState = HdcpSupportState + joinOffset;
|
||||
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||
InputStreamCardStatus = InputStreamCardStatus + joinOffset;
|
||||
OutputStreamCardStatus = OutputStreamCardStatus + joinOffset;
|
||||
OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset;
|
||||
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.DM;
|
||||
using PepperDash.Essentials.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
//using PepperDash.Essentials.Room.MobileControl;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
@@ -53,7 +53,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString());
|
||||
|
||||
// Check if User/ProgramX exists
|
||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
|
||||
@@ -290,33 +290,14 @@ namespace PepperDash.Essentials
|
||||
|
||||
DeviceManager.ActivateAll();
|
||||
|
||||
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl;
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.LinkSystemMonitorToAppServer();
|
||||
//LinkSystemMonitorToAppServer();
|
||||
|
||||
}
|
||||
|
||||
//void LinkSystemMonitorToAppServer()
|
||||
//{
|
||||
// var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
|
||||
|
||||
// var appServer = DeviceManager.GetDeviceForKey("appServer") as MobileControlSystemController;
|
||||
|
||||
|
||||
// if (sysMon != null && appServer != null)
|
||||
// {
|
||||
// var key = sysMon.Key + "-" + appServer.Key;
|
||||
// var messenger = new PepperDash.Essentials.AppServer.Messengers.SystemMonitorMessenger
|
||||
// (key, sysMon, "/device/systemMonitor");
|
||||
|
||||
// messenger.RegisterWithAppServer(appServer);
|
||||
|
||||
// DeviceManager.AddDevice(messenger);
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all devices from config and adds them to DeviceManager
|
||||
/// </summary>
|
||||
@@ -342,7 +323,12 @@ namespace PepperDash.Essentials
|
||||
// Skip this to prevent unnecessary warnings
|
||||
if (devConf.Key == "processor")
|
||||
{
|
||||
if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower())
|
||||
var prompt = Global.ControlSystem.ControllerPrompt;
|
||||
|
||||
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) &&
|
||||
String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!typeMatch)
|
||||
Debug.Console(0,
|
||||
"WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available",
|
||||
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
|
||||
@@ -394,19 +380,14 @@ namespace PepperDash.Essentials
|
||||
if (newDev == null)
|
||||
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
|
||||
|
||||
//
|
||||
//if (newDev == null)
|
||||
// newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
|
||||
//
|
||||
|
||||
if (newDev != null)
|
||||
DeviceManager.AddDevice(newDev);
|
||||
else
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded.");
|
||||
@@ -456,19 +437,34 @@ namespace PepperDash.Essentials
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
||||
if (room != null)
|
||||
{
|
||||
// default IPID
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
// default to no join map key
|
||||
string fusionJoinMapKey = string.Empty;
|
||||
|
||||
if (room.Config.Properties["fusion"] != null)
|
||||
{
|
||||
Debug.Console(2, "Custom Fusion config found. Using custom values");
|
||||
|
||||
var fusionConfig = room.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
|
||||
|
||||
if (fusionConfig != null)
|
||||
{
|
||||
fusionIpId = fusionConfig.IpIdInt;
|
||||
fusionJoinMapKey = fusionConfig.JoinMapKey;
|
||||
}
|
||||
}
|
||||
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
|
||||
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
//DeviceManager.AddDevice(bridge);
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
@@ -477,13 +473,21 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
|
||||
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
//DeviceManager.AddDevice(bridge);
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else if (room is EssentialsTechRoom)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
@@ -504,34 +508,35 @@ namespace PepperDash.Essentials
|
||||
|
||||
private static void CreateMobileControlBridge(EssentialsRoomBase room)
|
||||
{
|
||||
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl;
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.CreateMobileControlRoomBridge(room);
|
||||
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helps add the post activation steps that link bridges to main controller
|
||||
/// </summary>
|
||||
/// <param name="bridge"></param>
|
||||
//void AddBridgePostActivationHelper(MobileControlBridgeBase bridge)
|
||||
//{
|
||||
// bridge.AddPostActivationAction(() =>
|
||||
// {
|
||||
// var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
|
||||
// if (parent == null)
|
||||
// {
|
||||
// Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present");
|
||||
// return;
|
||||
// }
|
||||
// Debug.Console(0, bridge, "Linking to parent controller");
|
||||
// bridge.AddParent(parent);
|
||||
// parent.AddBridge(bridge);
|
||||
// });
|
||||
//}
|
||||
private static IMobileControl GetMobileControlDevice()
|
||||
{
|
||||
var mobileControlList = DeviceManager.AllDevices.OfType<IMobileControl>().ToList();
|
||||
|
||||
if (mobileControlList.Count > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning,
|
||||
"Multiple instances of Mobile Control Server found.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mobileControlList.Count > 0)
|
||||
{
|
||||
return mobileControlList[0];
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control not enabled for this system");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires up a logo server if not already running
|
||||
@@ -568,23 +573,31 @@ namespace PepperDash.Essentials
|
||||
string logoLight = null;
|
||||
string logo = null;
|
||||
|
||||
if (c.Properties["logoDark"] != null)
|
||||
try
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
if (c.Properties["logoDark"] != null)
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logoLight"] != null)
|
||||
if (c.Properties["logoLight"] != null)
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
BooleanSigData CodecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
||||
: base(room, ipId)
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||
: base(room, ipId, joinMapKey)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -55,25 +55,25 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Map FusionRoom Attributes:
|
||||
|
||||
// Codec volume
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig);
|
||||
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
||||
|
||||
// In Call Status
|
||||
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
||||
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
||||
|
||||
// Online status
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
var c = codec as ICommunicationMonitor;
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||
c.CommunicationMonitor.StatusChange += (o, a) =>
|
||||
{
|
||||
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
||||
};
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.AttributeName);
|
||||
}
|
||||
|
||||
// Codec IP Address
|
||||
@@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
if (codecHasIpInfo)
|
||||
{
|
||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||
|
||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
|
||||
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||
@@ -166,20 +166,19 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
// Room to fusion room
|
||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||
|
||||
// Moved to
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
|
||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
|
||||
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
|
||||
|
||||
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||
@@ -197,9 +196,9 @@ namespace PepperDash.Essentials.Fusion
|
||||
uint i = 1;
|
||||
foreach (var kvp in setTopBoxes)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -207,7 +206,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
i = 1;
|
||||
foreach (var kvp in discPlayers)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
break;
|
||||
@@ -217,9 +216,9 @@ namespace PepperDash.Essentials.Fusion
|
||||
i = 1;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 10) // We only have ten spots???
|
||||
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -273,14 +272,17 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Display to fusion room sigs
|
||||
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
|
||||
var defaultDisplayTwoWay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultDisplayTwoWay != null)
|
||||
{
|
||||
defaultDisplayTwoWay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
}
|
||||
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
|
||||
|
||||
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
||||
|
||||
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
|
||||
@@ -302,8 +304,18 @@ namespace PepperDash.Essentials.Fusion
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
||||
|
||||
|
||||
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
}
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
@@ -315,7 +327,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
}
|
||||
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
|
||||
{
|
||||
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
@@ -325,12 +337,17 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Power Off
|
||||
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
var displayTwoWay = display as IHasPowerControlWithFeedback;
|
||||
if (displayTwoWay != null)
|
||||
{
|
||||
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
}
|
||||
|
||||
// Current Source
|
||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
public class EssentialsTechRoomFusionSystemController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
{
|
||||
public EssentialsTechRoomFusionSystemController(EssentialsTechRoom room, uint ipId, string joinMapKey)
|
||||
: base(room, ipId, joinMapKey)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void SetUpDisplay()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var displays = (Room as EssentialsTechRoom).Displays;
|
||||
|
||||
Debug.Console(1, this, "Setting up Static Assets for {0} Displays", displays.Count);
|
||||
|
||||
foreach (var display in displays.Values.Cast<DisplayBase>())
|
||||
{
|
||||
var disp = display; // Local scope variable
|
||||
|
||||
Debug.Console(2, this, "Setting up Static Asset for {0}", disp.Key);
|
||||
|
||||
disp.UsageTracker = new UsageTracking(disp) { UsageIsTracked = true };
|
||||
disp.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
|
||||
var dispPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
disp.PowerOn();
|
||||
}
|
||||
});
|
||||
var dispPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
disp.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(disp.Key);
|
||||
|
||||
FusionAsset tempAsset;
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
// Used existing asset
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
|
||||
disp.Name, "Display", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
|
||||
if (dispAsset != null)
|
||||
{
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(disp);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(disp);
|
||||
}
|
||||
|
||||
var defaultTwoWayDisplay = disp as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (disp is IDisplayUsage)
|
||||
{
|
||||
(disp as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
}
|
||||
|
||||
if(dispAsset != null)
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up displays in Fusion: {0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -133,6 +133,7 @@
|
||||
<Compile Include="Devices\Amplifier.cs" />
|
||||
<Compile Include="ControlSystem.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||
<Compile Include="Fusion\EssentialsTechRoomFusionSystemController.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
|
||||
@@ -141,11 +142,13 @@
|
||||
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsTechRoomConfig.cs" />
|
||||
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
|
||||
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
|
||||
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
|
||||
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
||||
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||
|
||||
@@ -22,30 +22,25 @@ namespace PepperDash.Essentials.Room.Config
|
||||
public static Device GetRoomObject(DeviceConfig roomConfig)
|
||||
{
|
||||
var typeName = roomConfig.Type.ToLower();
|
||||
|
||||
if (typeName == "huddle")
|
||||
{
|
||||
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
|
||||
return huddle;
|
||||
return new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
}
|
||||
else if (typeName == "huddlevtc1")
|
||||
{
|
||||
var rm = new EssentialsHuddleVtc1Room(roomConfig);
|
||||
|
||||
return rm;
|
||||
}
|
||||
else if (typeName == "ddvc01Bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
else if (typeName == "dualdisplay")
|
||||
{
|
||||
var rm = new EssentialsDualDisplayRoom(roomConfig);
|
||||
if (typeName == "huddlevtc1")
|
||||
{
|
||||
return new EssentialsHuddleVtc1Room(roomConfig);
|
||||
}
|
||||
if (typeName == "ddvc01bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
if (typeName == "dualdisplay")
|
||||
{
|
||||
return new EssentialsDualDisplayRoom(roomConfig);
|
||||
}
|
||||
|
||||
return rm;
|
||||
}
|
||||
|
||||
return null;
|
||||
return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,6 +177,9 @@ namespace PepperDash.Essentials.Room.Config
|
||||
[JsonProperty("volumes")]
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
|
||||
[JsonProperty("fusion")]
|
||||
public EssentialsRoomFusionConfig Fusion { get; set; }
|
||||
|
||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
|
||||
@@ -225,6 +223,32 @@ namespace PepperDash.Essentials.Room.Config
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomFusionConfig
|
||||
{
|
||||
public uint IpIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(IpId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("ipId")]
|
||||
public string IpId { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomMicrophonePrivacyConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
|
||||
72
PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
Normal file
72
PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
public class EssentialsTechRoomConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The key of the dummy device used to enable routing
|
||||
/// </summary>
|
||||
[JsonProperty("dummySourceKey")]
|
||||
public string DummySourceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The keys of the displays assigned to this room
|
||||
/// </summary>
|
||||
[JsonProperty("displays")]
|
||||
public List<string> Displays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The keys of the tuners assinged to this room
|
||||
/// </summary>
|
||||
[JsonProperty("tuners")]
|
||||
public List<string> Tuners { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PIN to access the room as a normal user
|
||||
/// </summary>
|
||||
[JsonProperty("userPin")]
|
||||
public string UserPin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PIN to access the room as a tech user
|
||||
/// </summary>
|
||||
[JsonProperty("techPin")]
|
||||
public string TechPin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the presets file. Path prefix is assumed to be /html/presets/lists/
|
||||
/// </summary>
|
||||
[JsonProperty("presetsFileName")]
|
||||
public string PresetsFileName { get; set; }
|
||||
|
||||
[JsonProperty("scheduledEvents")]
|
||||
public List<ScheduledEventConfig> ScheduledEvents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the room is the primary when true
|
||||
/// </summary>
|
||||
[JsonProperty("isPrimary")]
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which tuners should mirror preset recall when two rooms are configured in a primary->secondary scenario
|
||||
/// </summary>
|
||||
[JsonProperty("mirroredTuners")]
|
||||
public Dictionary<uint, string> MirroredTuners { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the room
|
||||
/// </summary>
|
||||
[JsonProperty("isTvPresetsProvider")]
|
||||
public bool IsTvPresetsProvider;
|
||||
|
||||
public EssentialsTechRoomConfig()
|
||||
{
|
||||
Displays = new List<string>();
|
||||
Tuners = new List<string>();
|
||||
ScheduledEvents = new List<ScheduledEventConfig>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,28 +274,45 @@ namespace PepperDash.Essentials
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SourceListKey = "default";
|
||||
SetSourceListKey();
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InitializeDisplay(DisplayBase disp)
|
||||
{
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
disp.CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
disp.CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
@@ -329,7 +346,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
@@ -579,8 +595,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
|
||||
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -176,15 +176,19 @@ namespace PepperDash.Essentials
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
@@ -197,11 +201,25 @@ namespace PepperDash.Essentials
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
}
|
||||
|
||||
SetSourceListKey();
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||
@@ -252,7 +270,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
@@ -495,8 +512,8 @@ namespace PepperDash.Essentials
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash_Essentials_Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -51,20 +51,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
//************************
|
||||
|
||||
public override string SourceListKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SourceListKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
_SourceListKey = value;
|
||||
SetCodecExternalSources();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
@@ -190,6 +176,12 @@ namespace PepperDash.Essentials
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
|
||||
var vc = VideoCodec as IHasExternalSourceSwitching;
|
||||
if (vc != null)
|
||||
{
|
||||
vc.SetSelectedSource(CurrentSourceInfoKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
@@ -273,19 +265,23 @@ namespace PepperDash.Essentials
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
@@ -328,7 +324,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SourceListKey = "default";
|
||||
SetSourceListKey();
|
||||
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -337,6 +334,21 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
SetCodecExternalSources();
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
|
||||
@@ -360,13 +372,14 @@ namespace PepperDash.Essentials
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -383,6 +396,8 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||
|
||||
RunRouteAction("roomOff");
|
||||
VideoCodec.StopSharing();
|
||||
VideoCodec.StandbyActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -580,6 +595,28 @@ namespace PepperDash.Essentials
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
if (OnFeedback.BoolValue)
|
||||
{
|
||||
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
|
||||
{
|
||||
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
|
||||
VideoCodec.StandbyDeactivate();
|
||||
}
|
||||
|
||||
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
|
||||
{
|
||||
VideoCodec.StandbyDeactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
|
||||
}
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
@@ -640,8 +677,9 @@ namespace PepperDash.Essentials
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -693,37 +731,44 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||
/// </summary>
|
||||
private void SetCodecExternalSources()
|
||||
{
|
||||
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||
/// <summary>
|
||||
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||
/// </summary>
|
||||
private void SetCodecExternalSources()
|
||||
{
|
||||
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||
|
||||
if (videoCodecWithExternalSwitching == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort;
|
||||
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
|
||||
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||
try
|
||||
{
|
||||
// Get the tie line that the external switcher is connected to
|
||||
string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
|
||||
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
|
||||
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
|
||||
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||
|
||||
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||
{
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
|
||||
videoCodecWithExternalSwitching.AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||
{
|
||||
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCodecBranding()
|
||||
{
|
||||
|
||||
513
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
513
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
@@ -0,0 +1,513 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
|
||||
{
|
||||
private readonly EssentialsTechRoomConfig _config;
|
||||
private readonly Dictionary<string, TwoWayDisplayBase> _displays;
|
||||
|
||||
private readonly DevicePresetsModel _tunerPresets;
|
||||
private readonly Dictionary<string, IRSetTopBoxBase> _tuners;
|
||||
|
||||
private Dictionary<string, string> _currentPresets;
|
||||
private ScheduledEventGroup _roomScheduledEventGroup;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue);
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsTechRoom(DeviceConfig config) : base(config)
|
||||
{
|
||||
_config = config.Properties.ToObject<EssentialsTechRoomConfig>();
|
||||
|
||||
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName);
|
||||
|
||||
_tunerPresets.SetFileName(_config.PresetsFileName);
|
||||
|
||||
_tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
|
||||
|
||||
_tuners = GetDevices<IRSetTopBoxBase>(_config.Tuners);
|
||||
_displays = GetDevices<TwoWayDisplayBase>(_config.Displays);
|
||||
|
||||
RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
|
||||
|
||||
SetUpTunerPresetsFeedback();
|
||||
|
||||
SubscribeToDisplayFeedbacks();
|
||||
|
||||
CreateOrUpdateScheduledEvents();
|
||||
}
|
||||
|
||||
public Dictionary<string, StringFeedback> CurrentPresetsFeedbacks { get; private set; }
|
||||
|
||||
public Dictionary<string, IRSetTopBoxBase> Tuners
|
||||
{
|
||||
get { return _tuners; }
|
||||
}
|
||||
|
||||
public Dictionary<string, TwoWayDisplayBase> Displays
|
||||
{
|
||||
get { return _displays; }
|
||||
}
|
||||
|
||||
public BoolFeedback RoomPowerIsOnFeedback { get; private set; }
|
||||
|
||||
public bool RoomPowerIsOn
|
||||
{
|
||||
get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); }
|
||||
}
|
||||
|
||||
#region ITvPresetsProvider Members
|
||||
|
||||
public DevicePresetsModel TvPresets
|
||||
{
|
||||
get { return _tunerPresets; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
||||
{
|
||||
if (!_currentPresets.ContainsKey(device.Key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentPresets[device.Key] = channel;
|
||||
|
||||
if (!CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||
{
|
||||
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUpTunerPresetsFeedback()
|
||||
{
|
||||
_currentPresets = new Dictionary<string, string>();
|
||||
CurrentPresetsFeedbacks = new Dictionary<string, StringFeedback>();
|
||||
|
||||
foreach (var setTopBox in _tuners)
|
||||
{
|
||||
var tuner = setTopBox.Value;
|
||||
_currentPresets.Add(tuner.Key, String.Empty);
|
||||
CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key]));
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToDisplayFeedbacks()
|
||||
{
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
display.Value.PowerIsOnFeedback.OutputChange +=
|
||||
(sender, args) =>
|
||||
{
|
||||
RoomPowerIsOnFeedback.InvokeFireUpdate();
|
||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateOrUpdateScheduledEvents()
|
||||
{
|
||||
var eventsConfig = _config.ScheduledEvents;
|
||||
|
||||
GetOrCreateScheduleGroup();
|
||||
|
||||
foreach (var eventConfig in eventsConfig)
|
||||
{
|
||||
CreateOrUpdateSingleEvent(eventConfig);
|
||||
}
|
||||
|
||||
_roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent;
|
||||
}
|
||||
|
||||
private void GetOrCreateScheduleGroup()
|
||||
{
|
||||
if (_roomScheduledEventGroup == null)
|
||||
{
|
||||
_roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key);
|
||||
|
||||
Scheduler.AddEventGroup(_roomScheduledEventGroup);
|
||||
}
|
||||
|
||||
_roomScheduledEventGroup.RetrieveAllEvents();
|
||||
}
|
||||
|
||||
private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent)
|
||||
{
|
||||
if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key))
|
||||
{
|
||||
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
|
||||
|
||||
//if (SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
|
||||
// SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
|
||||
//{
|
||||
// Debug.Console(1, this, "Existing event matches new event properties. Nothing to update");
|
||||
// return;
|
||||
//}
|
||||
|
||||
Debug.Console(1, this,
|
||||
"Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",
|
||||
roomEvent.Name);
|
||||
|
||||
_roomScheduledEventGroup.DeleteEvent(roomEvent);
|
||||
|
||||
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||
}
|
||||
|
||||
public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent)
|
||||
{
|
||||
//update config based on key of scheduleEvent
|
||||
GetOrCreateScheduleGroup();
|
||||
var existingEventIndex = _config.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
|
||||
|
||||
if (existingEventIndex < 0)
|
||||
{
|
||||
_config.ScheduledEvents.Add(scheduledEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.ScheduledEvents[existingEventIndex] = scheduledEvent;
|
||||
}
|
||||
|
||||
//create or update event based on config
|
||||
CreateOrUpdateSingleEvent(scheduledEvent);
|
||||
//save config
|
||||
Config.Properties = JToken.FromObject(_config);
|
||||
|
||||
CustomSetConfig(Config);
|
||||
//Fire Event
|
||||
OnScheduledEventUpdate();
|
||||
}
|
||||
|
||||
public List<ScheduledEventConfig> GetScheduledEvents()
|
||||
{
|
||||
return _config.ScheduledEvents ?? new List<ScheduledEventConfig>();
|
||||
}
|
||||
|
||||
private void OnScheduledEventUpdate()
|
||||
{
|
||||
var handler = ScheduledEventsChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.ScheduledEvents});
|
||||
}
|
||||
|
||||
public event EventHandler<ScheduledEventEventArgs> ScheduledEventsChanged;
|
||||
|
||||
private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
|
||||
{
|
||||
var eventConfig = _config.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
|
||||
|
||||
if (eventConfig == null)
|
||||
{
|
||||
Debug.Console(1, this, "Event with name {0} not found", schevent.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Running actions for event {0}", schevent.Name);
|
||||
|
||||
if (eventConfig.Acknowledgeable)
|
||||
{
|
||||
schevent.Acknowledge();
|
||||
}
|
||||
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count);
|
||||
|
||||
foreach (var a in eventConfig.Actions)
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
@"Attempting to run action:
|
||||
DeviceKey: {0}
|
||||
MethodName: {1}
|
||||
Params: {2}"
|
||||
, a.DeviceKey, a.MethodName, a.Params);
|
||||
DeviceJsonApi.DoDeviceAction(a);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void RoomPowerOn()
|
||||
{
|
||||
Debug.Console(2, this, "Room Powering On");
|
||||
|
||||
var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs;
|
||||
|
||||
if (dummySource == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to get source with key: {0}", _config.DummySourceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
RunDirectRoute(dummySource, display.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void RoomPowerOff()
|
||||
{
|
||||
Debug.Console(2, this, "Room Powering Off");
|
||||
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
display.Value.PowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, T> GetDevices<T>(ICollection<string> config) where T : IKeyed
|
||||
{
|
||||
try
|
||||
{
|
||||
var returnValue = DeviceManager.AllDevices.OfType<T>()
|
||||
.Where(d => config.Contains(d.Key))
|
||||
.ToDictionary(d => d.Key, d => d);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Error getting devices. Check Essentials Configuration");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsRoomBase
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get { return () => RoomPowerIsOn; }
|
||||
}
|
||||
|
||||
protected override void EndShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetDefaultLevels()
|
||||
{
|
||||
}
|
||||
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RunDefaultPresentRoute()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IBridgeAdvanced
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
|
||||
var joinMap = new EssentialsTechRoomJoinMap(joinStart);
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!String.IsNullOrEmpty(joinMapSerialized))
|
||||
{
|
||||
joinMap = JsonConvert.DeserializeObject<EssentialsTechRoomJoinMap>(joinMapSerialized);
|
||||
}
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
uint i;
|
||||
if (_config.IsPrimary)
|
||||
{
|
||||
Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring");
|
||||
if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0)
|
||||
{
|
||||
foreach (var tuner in _config.MirroredTuners)
|
||||
{
|
||||
var f = CurrentPresetsFeedbacks[tuner.Value];
|
||||
|
||||
if (f == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to find feedback with key: {0}", tuner.Value);
|
||||
continue;
|
||||
}
|
||||
|
||||
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
|
||||
f.LinkInputSig(trilist.StringInput[(uint)(join)]);
|
||||
Debug.Console(1, this, "Linked Current Preset feedback for tuner: {0} to serial join: {1}", tuner.Value, join);
|
||||
}
|
||||
}
|
||||
|
||||
//i = 0;
|
||||
//foreach (var feedback in CurrentPresetsFeedbacks)
|
||||
//{
|
||||
// feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]);
|
||||
// i++;
|
||||
//}
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var feedback in CurrentPresetsFeedbacks)
|
||||
{
|
||||
feedback.Value.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Linking Secondary system Tuner Preset Mirroring");
|
||||
|
||||
if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0)
|
||||
{
|
||||
foreach (var tuner in _config.MirroredTuners)
|
||||
{
|
||||
var t = _tuners[tuner.Value];
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value);
|
||||
continue;
|
||||
}
|
||||
|
||||
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
|
||||
trilist.SetStringSigAction(join, s => _tunerPresets.Dial(s, t));
|
||||
Debug.Console(1, this, "Linked preset recall action for tuner: {0} to serial join: {1}", tuner.Value, join);
|
||||
}
|
||||
|
||||
//foreach (var setTopBox in _tuners)
|
||||
//{
|
||||
// var tuner = setTopBox;
|
||||
|
||||
// trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value));
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("currentPreset")]
|
||||
public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16},
|
||||
new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial});
|
||||
|
||||
public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#region IRunDirectRouteAction Members
|
||||
|
||||
private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest)
|
||||
{
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to route directly between a source and destination
|
||||
/// </summary>
|
||||
/// <param name="sourceKey"></param>
|
||||
/// <param name="destinationKey"></param>
|
||||
public void RunDirectRoute(string sourceKey, string destinationKey)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink;
|
||||
|
||||
var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
|
||||
|
||||
if (source == null || dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey);
|
||||
return;
|
||||
}
|
||||
RunDirectRoute(source, dest);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class ScheduledEventEventArgs : EventArgs
|
||||
{
|
||||
public List<ScheduledEventConfig> ScheduledEvents;
|
||||
}
|
||||
}
|
||||
@@ -305,9 +305,9 @@ namespace PepperDash.Essentials
|
||||
TriList.SetSigFalseAction(UIBoolJoin.ShowPowerOffPress, EndMeetingPress);
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
|
||||
{
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
|
||||
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
|
||||
{
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
|
||||
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
|
||||
});
|
||||
|
||||
base.Show();
|
||||
@@ -984,8 +984,8 @@ namespace PepperDash.Essentials
|
||||
(previousDev as IDvr).UnlinkButtons(TriList);
|
||||
if (previousDev is INumericKeypad)
|
||||
(previousDev as INumericKeypad).UnlinkButtons(TriList);
|
||||
if (previousDev is IPower)
|
||||
(previousDev as IPower).UnlinkButtons(TriList);
|
||||
if (previousDev is IHasPowerControl)
|
||||
(previousDev as IHasPowerControl).UnlinkButtons(TriList);
|
||||
if (previousDev is ITransport)
|
||||
(previousDev as ITransport).UnlinkButtons(TriList);
|
||||
//if (previousDev is IRadio)
|
||||
@@ -1044,8 +1044,8 @@ namespace PepperDash.Essentials
|
||||
(dev as IDvr).LinkButtons(TriList);
|
||||
if (dev is INumericKeypad)
|
||||
(dev as INumericKeypad).LinkButtons(TriList);
|
||||
if (dev is IPower)
|
||||
(dev as IPower).LinkButtons(TriList);
|
||||
if (dev is IHasPowerControl)
|
||||
(dev as IHasPowerControl).LinkButtons(TriList);
|
||||
if (dev is ITransport)
|
||||
(dev as ITransport).LinkButtons(TriList);
|
||||
//if (dev is IRadio)
|
||||
|
||||
@@ -319,8 +319,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
|
||||
{
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
|
||||
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
|
||||
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
|
||||
});
|
||||
|
||||
SetupNextMeetingTimer();
|
||||
@@ -1293,8 +1293,8 @@ namespace PepperDash.Essentials
|
||||
(previousDev as IDvr).UnlinkButtons(TriList);
|
||||
if (previousDev is INumericKeypad)
|
||||
(previousDev as INumericKeypad).UnlinkButtons(TriList);
|
||||
if (previousDev is IPower)
|
||||
(previousDev as IPower).UnlinkButtons(TriList);
|
||||
if (previousDev is IHasPowerControl)
|
||||
(previousDev as IHasPowerControl).UnlinkButtons(TriList);
|
||||
if (previousDev is ITransport)
|
||||
(previousDev as ITransport).UnlinkButtons(TriList);
|
||||
}
|
||||
@@ -1351,8 +1351,8 @@ namespace PepperDash.Essentials
|
||||
(dev as IDvr).LinkButtons(TriList);
|
||||
if (dev is INumericKeypad)
|
||||
(dev as INumericKeypad).LinkButtons(TriList);
|
||||
if (dev is IPower)
|
||||
(dev as IPower).LinkButtons(TriList);
|
||||
if (dev is IHasPowerControl)
|
||||
(dev as IHasPowerControl).LinkButtons(TriList);
|
||||
if (dev is ITransport)
|
||||
(dev as ITransport).LinkButtons(TriList);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <summary>
|
||||
/// Bridge API using EISC
|
||||
/// </summary>
|
||||
public class EiscApiAdvanced : BridgeApi
|
||||
public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
|
||||
{
|
||||
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
@@ -98,13 +98,35 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
|
||||
Eisc.SigChange += Eisc_SigChange;
|
||||
|
||||
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000);
|
||||
|
||||
AddPostActivationAction(LinkDevices);
|
||||
AddPostActivationAction(LinkRooms);
|
||||
AddPostActivationAction(RegisterEisc);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
CommunicationMonitor.Start();
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
public override bool Deactivate()
|
||||
{
|
||||
CommunicationMonitor.Stop();
|
||||
return base.Deactivate();
|
||||
}
|
||||
|
||||
private void LinkDevices()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Devices...");
|
||||
|
||||
if (PropertiesConfig.Devices == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No devices linked to this bridge");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var d in PropertiesConfig.Devices)
|
||||
{
|
||||
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||
@@ -130,6 +152,14 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterEisc()
|
||||
{
|
||||
if (Eisc.Registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var registerResult = Eisc.Register();
|
||||
|
||||
@@ -142,6 +172,31 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||
}
|
||||
|
||||
public void LinkRooms()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Rooms...");
|
||||
|
||||
if (PropertiesConfig.Rooms == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No rooms linked to this bridge.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var room in PropertiesConfig.Rooms)
|
||||
{
|
||||
var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced;
|
||||
|
||||
if (rm == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice,
|
||||
"Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a join map
|
||||
/// </summary>
|
||||
@@ -280,6 +335,12 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#region Implementation of ICommunicationMonitor
|
||||
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class EiscApiPropertiesConfig
|
||||
@@ -290,6 +351,9 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
[JsonProperty("devices")]
|
||||
public List<ApiDevicePropertiesConfig> Devices { get; set; }
|
||||
|
||||
[JsonProperty("rooms")]
|
||||
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
|
||||
|
||||
|
||||
public class ApiDevicePropertiesConfig
|
||||
{
|
||||
@@ -303,6 +367,18 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
public class ApiRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("joinStart")]
|
||||
public uint JoinStart { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class EiscApiAdvancedFactory : EssentialsDeviceFactory<EiscApiAdvanced>
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
public AppleTvJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,14 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 1201, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Input HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("InputStreamCardState")]
|
||||
public JoinDataComplete InputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1501, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("OutputStreamCardState")]
|
||||
public JoinDataComplete OutputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1601, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("InputNames")]
|
||||
public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
|
||||
[JoinName("PirSensitivityInVacantState")]
|
||||
public JoinDataComplete PirSensitivityInVacantState = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Occ Sensor Ultrasonic Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
|
||||
new JoinMetadata { Description = "Occ Sensor PIR Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
|
||||
@@ -1,131 +1,274 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||
{
|
||||
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("IsOnline")]
|
||||
public JoinDataComplete IsOnline = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Is Online",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("IsOnline")]
|
||||
public JoinDataComplete IsOnline = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Is Online",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("Enable")]
|
||||
public JoinDataComplete Enable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Enable",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("Enable")]
|
||||
public JoinDataComplete Enable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Enable",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionSensed")]
|
||||
public JoinDataComplete PartitionSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 3,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("PartitionSensed")]
|
||||
public JoinDataComplete PartitionSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 3,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionNotSensed")]
|
||||
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 4,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Not Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("PartitionNotSensed")]
|
||||
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 4,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Not Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncreaseSensitivity")]
|
||||
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 6,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Increase Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("IncreaseSensitivity")]
|
||||
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 6,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Increase Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DecreaseSensitivity")]
|
||||
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 7,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Decrease Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("DecreaseSensitivity")]
|
||||
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 7,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Decrease Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Sensitivity")]
|
||||
public JoinDataComplete Sensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
[JoinName("Sensitivity")]
|
||||
public JoinDataComplete Sensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public GlsPartitionSensorJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof (GlsPartitionSensorJoinMap))
|
||||
{
|
||||
public GlsPartitionSensorJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof(GlsPartitionSensorJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
protected GlsPartitionSensorJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")]
|
||||
public class GlsPartitionSensorJoinMap:JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("IsOnline")]
|
||||
public JoinDataComplete IsOnline = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Is Online",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("Enable")]
|
||||
public JoinDataComplete Enable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Enable",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionSensed")]
|
||||
public JoinDataComplete PartitionSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 3,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionNotSensed")]
|
||||
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 4,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Not Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncreaseSensitivity")]
|
||||
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 6,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Increase Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DecreaseSensitivity")]
|
||||
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 7,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Decrease Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Sensitivity")]
|
||||
public JoinDataComplete Sensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public GlsPartitionSensorJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof(GlsPartitionSensorJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
/// <summary>
|
||||
/// Join map for IRBlurayBase devices
|
||||
/// </summary>
|
||||
public class IRBlurayBaseJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("PowerOn")]
|
||||
public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Power On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("PowerOff")]
|
||||
public JoinDataComplete PowerOff = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Power Off", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("PowerToggle")]
|
||||
public JoinDataComplete PowerToggle = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Power Toggle", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Up")]
|
||||
public JoinDataComplete Up = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Down")]
|
||||
public JoinDataComplete Down = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Left")]
|
||||
public JoinDataComplete Left = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Left", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Right")]
|
||||
public JoinDataComplete Right = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Right", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Select")]
|
||||
public JoinDataComplete Select = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Select", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Menu")]
|
||||
public JoinDataComplete Menu = new JoinDataComplete(new JoinData { JoinNumber = 9, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Menu", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Exit")]
|
||||
public JoinDataComplete Exit = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Exit", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit0")]
|
||||
public JoinDataComplete Digit0 = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 0", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit1")]
|
||||
public JoinDataComplete Digit1 = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 1", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit2")]
|
||||
public JoinDataComplete Digit2 = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 2", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit3")]
|
||||
public JoinDataComplete Digit3 = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 3", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit4")]
|
||||
public JoinDataComplete Digit4 = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 4", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit5")]
|
||||
public JoinDataComplete Digit5 = new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 5", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit6")]
|
||||
public JoinDataComplete Digit6 = new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 6", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit7")]
|
||||
public JoinDataComplete Digit7 = new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 7", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit8")]
|
||||
public JoinDataComplete Digit8 = new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 8", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit9")]
|
||||
public JoinDataComplete Digit9 = new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 9", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadClear")]
|
||||
public JoinDataComplete KeypadClear = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Clear", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadEnter")]
|
||||
public JoinDataComplete KeypadEnter = new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Enter", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChannelUp")]
|
||||
public JoinDataComplete ChannelUp = new JoinDataComplete(new JoinData { JoinNumber = 23, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "STB Channel Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChannelDown")]
|
||||
public JoinDataComplete ChannelDown = new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "STB Channel Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("LastChannel")]
|
||||
public JoinDataComplete LastChannel = new JoinDataComplete(new JoinData { JoinNumber = 25, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Last Channel", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Guide")]
|
||||
public JoinDataComplete Guide = new JoinDataComplete(new JoinData { JoinNumber = 26, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Guide", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Info")]
|
||||
public JoinDataComplete Info = new JoinDataComplete(new JoinData { JoinNumber = 27, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Info", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Red")]
|
||||
public JoinDataComplete Red = new JoinDataComplete(new JoinData { JoinNumber = 28, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Red", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Green")]
|
||||
public JoinDataComplete Green = new JoinDataComplete(new JoinData { JoinNumber = 29, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Green", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Yellow")]
|
||||
public JoinDataComplete Yellow = new JoinDataComplete(new JoinData { JoinNumber = 30, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Yellow", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Blue")]
|
||||
public JoinDataComplete Blue = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Blue", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
|
||||
[JoinName("Play")]
|
||||
public JoinDataComplete Play = new JoinDataComplete(new JoinData { JoinNumber = 33, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Play", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Pause")]
|
||||
public JoinDataComplete Pause = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Pause", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Stop")]
|
||||
public JoinDataComplete Stop = new JoinDataComplete(new JoinData { JoinNumber = 35, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Stop", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("FFwd")]
|
||||
public JoinDataComplete FFwd = new JoinDataComplete(new JoinData { JoinNumber = 36, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "FFwd", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Rewind")]
|
||||
public JoinDataComplete Rewind = new JoinDataComplete(new JoinData { JoinNumber = 37, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Rewind", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChapPlus")]
|
||||
public JoinDataComplete ChapPlus = new JoinDataComplete(new JoinData { JoinNumber = 38, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Chapter Plus", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChapMinus")]
|
||||
public JoinDataComplete ChapMinus = new JoinDataComplete(new JoinData { JoinNumber = 39, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Chapter Minus", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Replay")]
|
||||
public JoinDataComplete Replay = new JoinDataComplete(new JoinData { JoinNumber = 40, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Replay", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Record")]
|
||||
public JoinDataComplete Record = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Record", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("HasKeypadAccessoryButton1")]
|
||||
public JoinDataComplete HasKeypadAccessoryButton1 = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Has Keypad Accessory Button 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("HasKeypadAccessoryButton2")]
|
||||
public JoinDataComplete HasKeypadAccessoryButton2 = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Has Keypad Accessory Button 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadAccessoryButton1Press")]
|
||||
public JoinDataComplete KeypadAccessoryButton1Press = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 2 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 1 Press", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadAccessoryButton2Press")]
|
||||
public JoinDataComplete KeypadAccessoryButton2Press = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 2 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 2 Press", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadAccessoryButton1Label")]
|
||||
public JoinDataComplete KeypadAccessoryButton1Label = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 1 Label", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("KeypadAccessoryButton2Label")]
|
||||
public JoinDataComplete KeypadAccessoryButton2Label = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 1 Label", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public IRBlurayBaseJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof(IRBlurayBaseJoinMap))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
protected IRBlurayBaseJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public class SetTopBoxControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public class SetTopBoxControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("PowerOn")]
|
||||
public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "STB Power On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
@@ -236,5 +236,5 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,6 +56,11 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private void RegisterAndConfigureComPort()
|
||||
{
|
||||
if (Port == null)
|
||||
{
|
||||
Debug.Console(0,this,Debug.ErrorLogLevel.Error, "Configured com Port for this device does not exist.");
|
||||
return;
|
||||
}
|
||||
if (Port.Parent is CrestronControlSystem)
|
||||
{
|
||||
var result = Port.Register();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace PepperDash.Essentials.Core
|
||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||
return dev.ComPorts[config.ControlPortNumber];
|
||||
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
Debug.Console(0,Debug.ErrorLogLevel.Notice, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
@@ -27,7 +29,7 @@ namespace PepperDash.Essentials.Core.Config
|
||||
public List<TieLineConfig> TieLines { get; set; }
|
||||
|
||||
[JsonProperty("joinMaps")]
|
||||
public Dictionary<string, string> JoinMaps { get; set; }
|
||||
public Dictionary<string, JObject> JoinMaps { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
|
||||
|
||||
@@ -1,195 +1,195 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the ConfigObject from the file
|
||||
/// </summary>
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the ConfigObject from the file
|
||||
/// </summary>
|
||||
public class ConfigReader
|
||||
{
|
||||
public const string LocalConfigPresent =
|
||||
@"
|
||||
***************************************************
|
||||
************* Using Local config file *************
|
||||
***************************************************";
|
||||
|
||||
public static EssentialsConfig ConfigObject { get; private set; }
|
||||
|
||||
public static bool LoadConfig2()
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
|
||||
try
|
||||
{
|
||||
// Check for local config file first
|
||||
var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
|
||||
|
||||
bool localConfigFound = false;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
|
||||
|
||||
// Check for local config directory first
|
||||
|
||||
var configFiles = GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
if(configFiles.Length == 1)
|
||||
{
|
||||
***************************************************";
|
||||
|
||||
public static EssentialsConfig ConfigObject { get; private set; }
|
||||
|
||||
public static bool LoadConfig2()
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
|
||||
try
|
||||
{
|
||||
// Check for local config file first
|
||||
var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
|
||||
|
||||
bool localConfigFound = false;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
|
||||
|
||||
// Check for local config directory first
|
||||
|
||||
var configFiles = GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
if(configFiles.Length == 1)
|
||||
{
|
||||
localConfigFound = true;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Local Configuration file not present.", filePath);
|
||||
|
||||
}
|
||||
|
||||
// Check for Portal Config
|
||||
if(!localConfigFound)
|
||||
{
|
||||
filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
|
||||
|
||||
configFiles = GetConfigFiles(filePath);
|
||||
|
||||
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 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
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"ERROR: Portal Configuration file not present. Please load file and reset program.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the actual file path
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Local Configuration file not present.", filePath);
|
||||
|
||||
}
|
||||
|
||||
// Check for Portal Config
|
||||
if(!localConfigFound)
|
||||
{
|
||||
filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
|
||||
|
||||
configFiles = GetConfigFiles(filePath);
|
||||
|
||||
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 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
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"ERROR: Portal Configuration file not present. Please load file and reset program.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the actual file path
|
||||
filePath = configFiles[0].FullName;
|
||||
|
||||
// Generate debug statement if using a local file.
|
||||
if (localConfigFound)
|
||||
{
|
||||
GetLocalFileMessage(filePath);
|
||||
}
|
||||
|
||||
// Read the file
|
||||
using (StreamReader fs = new StreamReader(filePath))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
|
||||
|
||||
if (localConfigFound)
|
||||
{
|
||||
ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject<EssentialsConfig>();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
||||
|
||||
// Extract SystemUrl and TemplateUrl into final config output
|
||||
|
||||
if (doubleObj["system_url"] != null)
|
||||
{
|
||||
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
||||
}
|
||||
|
||||
if (doubleObj["template_url"] != null)
|
||||
{
|
||||
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the files from the directory specified.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static FileInfo[] GetConfigFiles(string filePath)
|
||||
{
|
||||
// Get the directory
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Debug.Console(1, "Searching in Directory '{0}'", dir);
|
||||
// Get the directory info
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
|
||||
// Get the file name
|
||||
var fileName = Path.GetFileName(filePath);
|
||||
Debug.Console(1, "For Config Files matching: '{0}'", fileName);
|
||||
|
||||
// Get the files that match from the directory
|
||||
return dirInfo.GetFiles(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Directory not found: ", dir);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the group for a given device key in config
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetGroupForDeviceKey(string key)
|
||||
{
|
||||
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
return dev == null ? null : dev.Group;
|
||||
}
|
||||
|
||||
// Read the file
|
||||
using (StreamReader fs = new StreamReader(filePath))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
|
||||
|
||||
if (localConfigFound)
|
||||
{
|
||||
ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject<EssentialsConfig>();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
||||
|
||||
// Extract SystemUrl and TemplateUrl into final config output
|
||||
|
||||
if (doubleObj["system_url"] != null)
|
||||
{
|
||||
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
||||
}
|
||||
|
||||
if (doubleObj["template_url"] != null)
|
||||
{
|
||||
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the files from the directory specified.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static FileInfo[] GetConfigFiles(string filePath)
|
||||
{
|
||||
// Get the directory
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Debug.Console(1, "Searching in Directory '{0}'", dir);
|
||||
// Get the directory info
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
|
||||
// Get the file name
|
||||
var fileName = Path.GetFileName(filePath);
|
||||
Debug.Console(1, "For Config Files matching: '{0}'", fileName);
|
||||
|
||||
// Get the files that match from the directory
|
||||
return dirInfo.GetFiles(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Directory not found: ", dir);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the group for a given device key in config
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetGroupForDeviceKey(string key)
|
||||
{
|
||||
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
return dev == null ? null : dev.Group;
|
||||
}
|
||||
|
||||
private static void GetLocalFileMessage(string filePath)
|
||||
@@ -248,7 +248,7 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
Debug.Console(2, Debug.ErrorLogLevel.Notice, "Found Local config file: '{0}'", filePath);
|
||||
Debug.Console(0, newDebugString.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,38 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
[Description("Wrapper class for Digital Input")]
|
||||
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
{
|
||||
public DigitalInput InputPort { get; private set; }
|
||||
|
||||
public BoolFeedback InputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> InputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.State;
|
||||
}
|
||||
}
|
||||
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
{
|
||||
public DigitalInput InputPort { get; private set; }
|
||||
|
||||
public BoolFeedback InputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> InputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.State;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
|
||||
IOPortConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
@@ -40,15 +41,15 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
InputPort.Register();
|
||||
|
||||
InputPort.StateChange += InputPort_StateChange;
|
||||
InputPort.StateChange += InputPort_StateChange;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||
{
|
||||
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||
{
|
||||
InputStateFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.Console(0, "GetDigitalInput: Device '0' is not a valid IRelayPorts Device", dc.PortDeviceKey);
|
||||
Debug.Console(0, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -99,13 +100,13 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new IDigitalInputJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
var joinMap = new IDigitalInputJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
@@ -115,19 +116,19 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.Console(1, this, "Error: {0}", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.Console(1, this, "Error: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Relay Device");
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Digital Input Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
@@ -158,7 +159,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,15 +4,21 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic digital input deviced tied to a versiport
|
||||
/// </summary>
|
||||
public class GenericVersiportDigitalInputDevice : EssentialsDevice, IDigitalInput
|
||||
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
{
|
||||
public Versiport InputPort { get; private set; }
|
||||
|
||||
@@ -26,17 +32,29 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
}
|
||||
|
||||
public GenericVersiportDigitalInputDevice(string key, Versiport inputPort, IOPortConfig props):
|
||||
base(key)
|
||||
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
||||
base(key, name)
|
||||
{
|
||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||
InputPort = inputPort;
|
||||
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||
if (props.DisablePullUpResistor)
|
||||
InputPort.DisablePullUpResistor = true;
|
||||
InputPort.VersiportChange += new VersiportEventHandler(InputPort_VersiportChange);
|
||||
|
||||
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", props.PortNumber, InputPort.DisablePullUpResistor);
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
InputPort = postActivationFunc(config);
|
||||
|
||||
InputPort.Register();
|
||||
|
||||
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||
if (config.DisablePullUpResistor)
|
||||
InputPort.DisablePullUpResistor = true;
|
||||
|
||||
InputPort.VersiportChange += InputPort_VersiportChange;
|
||||
|
||||
|
||||
|
||||
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
|
||||
@@ -46,5 +64,105 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
if(args.Event == eVersiportEvent.DigitalInChange)
|
||||
InputStateFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new IDigitalInputJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.Console(1, this, "Error: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
|
||||
{
|
||||
|
||||
IIOPorts ioPortDevice;
|
||||
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsVersiport)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Processor does not support Versiports");
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = Global.ControlSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
|
||||
if (ioPortDev == null)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = ioPortDev;
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
}
|
||||
|
||||
return ioPortDevice.VersiPorts[dc.PortNumber];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
|
||||
{
|
||||
public GenericVersiportDigitalInputDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "versiportinput" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Versiport Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
if (props == null) return null;
|
||||
|
||||
var portDevice = new GenericVersiportDigitalInputDevice(dc.Key, dc.Name, GenericVersiportDigitalInputDevice.GetVersiportDigitalInput, props);
|
||||
|
||||
return portDevice;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic device controlled by relays
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic device controlled by relays
|
||||
/// </summary>
|
||||
[Description("Wrapper class for a Relay")]
|
||||
public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput
|
||||
{
|
||||
public Relay RelayOutput { get; private set; }
|
||||
|
||||
public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput
|
||||
{
|
||||
public Relay RelayOutput { get; private set; }
|
||||
|
||||
public BoolFeedback OutputIsOnFeedback { get; private set; }
|
||||
|
||||
//Maintained for compatibility with PepperDash.Essentials.Core.Devices.CrestronProcessor
|
||||
@@ -94,11 +94,11 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#region Events
|
||||
|
||||
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
|
||||
{
|
||||
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
|
||||
{
|
||||
OutputIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
@@ -119,33 +119,33 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
OpenRelay();
|
||||
else
|
||||
CloseRelay();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISwitchedOutput Members
|
||||
|
||||
void ISwitchedOutput.On()
|
||||
{
|
||||
CloseRelay();
|
||||
}
|
||||
|
||||
void ISwitchedOutput.Off()
|
||||
{
|
||||
OpenRelay();
|
||||
}
|
||||
|
||||
|
||||
#region ISwitchedOutput Members
|
||||
|
||||
void ISwitchedOutput.On()
|
||||
{
|
||||
CloseRelay();
|
||||
}
|
||||
|
||||
void ISwitchedOutput.Off()
|
||||
{
|
||||
OpenRelay();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GenericRelayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
var joinMap = new GenericRelayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericRelayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
@@ -155,26 +155,26 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
if (RelayOutput == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.Relay.JoinNumber, b =>
|
||||
{
|
||||
if (b)
|
||||
CloseRelay();
|
||||
else
|
||||
OpenRelay();
|
||||
});
|
||||
|
||||
// feedback for relay state
|
||||
|
||||
}
|
||||
|
||||
if (RelayOutput == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.Relay.JoinNumber, b =>
|
||||
{
|
||||
if (b)
|
||||
CloseRelay();
|
||||
else
|
||||
OpenRelay();
|
||||
});
|
||||
|
||||
// feedback for relay state
|
||||
|
||||
OutputIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Relay.JoinNumber]);
|
||||
}
|
||||
|
||||
@@ -202,54 +202,54 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
return portDevice;
|
||||
|
||||
|
||||
/*
|
||||
if (props.PortDeviceKey == "processor")
|
||||
portDevice = Global.ControlSystem as IRelayPorts;
|
||||
else
|
||||
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts;
|
||||
|
||||
if (portDevice == null)
|
||||
Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key);
|
||||
else
|
||||
{
|
||||
var cs = (portDevice as CrestronControlSystem);
|
||||
|
||||
if (cs != null)
|
||||
{
|
||||
// The relay is on a control system processor
|
||||
if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The relay is on another device type
|
||||
|
||||
if (props.PortNumber > portDevice.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Relay relay = portDevice.RelayPorts[props.PortNumber];
|
||||
|
||||
if (!relay.Registered)
|
||||
{
|
||||
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
return new GenericRelayDevice(key, relay);
|
||||
else
|
||||
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GenericRelayDevice(key, relay);
|
||||
}
|
||||
|
||||
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
|
||||
}
|
||||
/*
|
||||
if (props.PortDeviceKey == "processor")
|
||||
portDevice = Global.ControlSystem as IRelayPorts;
|
||||
else
|
||||
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts;
|
||||
|
||||
if (portDevice == null)
|
||||
Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key);
|
||||
else
|
||||
{
|
||||
var cs = (portDevice as CrestronControlSystem);
|
||||
|
||||
if (cs != null)
|
||||
{
|
||||
// The relay is on a control system processor
|
||||
if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The relay is on another device type
|
||||
|
||||
if (props.PortNumber > portDevice.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Relay relay = portDevice.RelayPorts[props.PortNumber];
|
||||
|
||||
if (!relay.Registered)
|
||||
{
|
||||
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
return new GenericRelayDevice(key, relay);
|
||||
else
|
||||
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GenericRelayDevice(key, relay);
|
||||
}
|
||||
|
||||
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -258,7 +258,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -130,6 +130,12 @@ namespace PepperDash.Essentials.Core
|
||||
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "OnlineStatusChange Event. Online = {0}", args.DeviceOnLine);
|
||||
|
||||
if (!Hardware.Registered)
|
||||
{
|
||||
return; // protects in cases where device has been unregistered and feedbacks would attempt to access null sigs.
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
if (feedback != null)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace PepperDash.Essentials.Core.DeviceInfo
|
||||
{
|
||||
public class DeviceInfo
|
||||
{
|
||||
public string HostName { get; set; }
|
||||
public string IpAddress { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string SerialNumber { get; set; }
|
||||
public string FirmwareVersion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceInfo
|
||||
{
|
||||
public class DeviceInfoEventArgs:EventArgs
|
||||
{
|
||||
public DeviceInfo DeviceInfo { get; set; }
|
||||
|
||||
public DeviceInfoEventArgs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DeviceInfoEventArgs(DeviceInfo devInfo)
|
||||
{
|
||||
DeviceInfo = devInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceInfo
|
||||
{
|
||||
public interface IDeviceInfoProvider:IKeyed
|
||||
{
|
||||
DeviceInfo DeviceInfo { get; }
|
||||
|
||||
event DeviceInfoChangeHandler DeviceInfoChanged;
|
||||
|
||||
void UpdateDeviceInfo();
|
||||
}
|
||||
|
||||
public delegate void DeviceInfoChangeHandler(IKeyed device, DeviceInfoEventArgs args);
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using PepperDash.Essentials.Core.SmartObjects;
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
|
||||
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IPower, ITransport, IUiDisplayInfo
|
||||
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IHasPowerControl, ITransport, IUiDisplayInfo
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasBranding
|
||||
{
|
||||
bool BrandingEnabled { get; }
|
||||
void InitializeBranding(string roomKey);
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface IHasBranding
|
||||
{
|
||||
bool BrandingEnabled { get; }
|
||||
void InitializeBranding(string roomKey);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using PepperDash.Essentials.Core;
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasPhoneDialing
|
||||
{
|
||||
@@ -11,4 +12,18 @@ namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
void EndPhoneCall();
|
||||
void SendDtmfToPhone(string digit);
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface IHasPhoneDialing
|
||||
{
|
||||
BoolFeedback PhoneOffHookFeedback { get; }
|
||||
StringFeedback CallerIdNameFeedback { get; }
|
||||
StringFeedback CallerIdNumberFeedback { get; }
|
||||
void DialPhoneCall(string number);
|
||||
void EndPhoneCall();
|
||||
void SendDtmfToPhone(string digit);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ILanguageDefinition
|
||||
{
|
||||
@@ -15,4 +15,21 @@ namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
List<LanguageLabel> DestinationGroupNames { get; set; }
|
||||
List<LanguageLabel> RoomNames { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface ILanguageDefinition
|
||||
{
|
||||
string LocaleName { get; set; }
|
||||
string FriendlyName { get; set; }
|
||||
bool Enable { get; set; }
|
||||
List<LanguageLabel> UiLabels { get; set; }
|
||||
List<LanguageLabel> Sources { get; set; }
|
||||
List<LanguageLabel> Destinations { get; set; }
|
||||
List<LanguageLabel> SourceGroupNames { get; set; }
|
||||
List<LanguageLabel> DestinationGroupNames { get; set; }
|
||||
List<LanguageLabel> RoomNames { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
|
||||
public interface ILanguageProvider
|
||||
{
|
||||
ILanguageDefinition CurrentLanguage { get; set; }
|
||||
|
||||
event EventHandler CurrentLanguageChanged;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ILanguageProvider
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface ILanguageProvider
|
||||
{
|
||||
ILanguageDefinition CurrentLanguage { get; set; }
|
||||
|
||||
|
||||
@@ -8,11 +8,9 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
/// </summary>
|
||||
public interface IMobileControl : IKeyed
|
||||
{
|
||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room);
|
||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
|
||||
|
||||
void LinkSystemMonitorToAppServer();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -26,6 +24,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
|
||||
string QrCodeUrl { get; }
|
||||
|
||||
string QrCodeChecksum { get; }
|
||||
|
||||
string McServerUrl { get; }
|
||||
|
||||
string RoomName { get; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface INumericKeypad
|
||||
public interface INumericKeypad:IKeyed
|
||||
{
|
||||
void Digit0(bool pressRelease);
|
||||
void Digit1(bool pressRelease);
|
||||
|
||||
@@ -14,35 +14,64 @@ using PepperDash.Essentials.Core.SmartObjects;
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Defines the ability to power a device on and off
|
||||
/// </summary>
|
||||
[Obsolete("Will be replaced by IHasPowerControlWithFeedback")]
|
||||
public interface IPower
|
||||
{
|
||||
void PowerOn();
|
||||
void PowerOff();
|
||||
void PowerToggle();
|
||||
BoolFeedback PowerIsOnFeedback { get; }
|
||||
BoolFeedback PowerIsOnFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds feedback for current power state
|
||||
/// </summary>
|
||||
public interface IHasPowerControlWithFeedback : IHasPowerControl
|
||||
{
|
||||
BoolFeedback PowerIsOnFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the ability to power a device on and off
|
||||
/// </summary>
|
||||
public interface IHasPowerControl
|
||||
{
|
||||
void PowerOn();
|
||||
void PowerOff();
|
||||
void PowerToggle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class IPowerExtensions
|
||||
public static class IHasPowerControlExtensions
|
||||
{
|
||||
public static void LinkButtons(this IPower dev, BasicTriList triList)
|
||||
public static void LinkButtons(this IHasPowerControl dev, BasicTriList triList)
|
||||
{
|
||||
triList.SetSigFalseAction(101, dev.PowerOn);
|
||||
triList.SetSigFalseAction(102, dev.PowerOff);
|
||||
triList.SetSigFalseAction(103, dev.PowerToggle);
|
||||
dev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
|
||||
|
||||
var fbdev = dev as IHasPowerControlWithFeedback;
|
||||
if (fbdev != null)
|
||||
{
|
||||
fbdev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnlinkButtons(this IPower dev, BasicTriList triList)
|
||||
public static void UnlinkButtons(this IHasPowerControl dev, BasicTriList triList)
|
||||
{
|
||||
triList.ClearBoolSigAction(101);
|
||||
triList.ClearBoolSigAction(102);
|
||||
triList.ClearBoolSigAction(103);
|
||||
dev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
|
||||
|
||||
var fbdev = dev as IHasPowerControlWithFeedback;
|
||||
if (fbdev != null)
|
||||
{
|
||||
fbdev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
bool HasDpad { get; }
|
||||
|
||||
PepperDash.Essentials.Core.Presets.DevicePresetsModel PresetsModel { get; }
|
||||
PepperDash.Essentials.Core.Presets.DevicePresetsModel TvPresets { get; }
|
||||
void LoadPresets(string filePath);
|
||||
|
||||
void DvrList(bool pressRelease);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ITvPresetsProvider
|
||||
{
|
||||
DevicePresetsModel TvPresets { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using PepperDash.Core;
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public class LanguageLabel
|
||||
{
|
||||
@@ -9,4 +10,16 @@ namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
public string DisplayText { get; set; }
|
||||
public uint JoinNumber { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public class LanguageLabel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string DisplayText { get; set; }
|
||||
public uint JoinNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -83,13 +83,13 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns></returns>
|
||||
public static object GetPropertyByName(string deviceObjectPath, string propertyName)
|
||||
{
|
||||
var obj = FindObjectOnPath(deviceObjectPath);
|
||||
if(obj == null)
|
||||
var dev = FindObjectOnPath(deviceObjectPath);
|
||||
if(dev == null)
|
||||
return "{ \"error\":\"No Device\"}";
|
||||
|
||||
object prop = dev.GetType().GetCType().GetProperty(propertyName).GetValue(dev, null);
|
||||
|
||||
CType t = obj.GetType();
|
||||
|
||||
var prop = t.GetProperty(propertyName);
|
||||
// var prop = t.GetProperty(propertyName);
|
||||
if (prop != null)
|
||||
{
|
||||
return prop;
|
||||
|
||||
@@ -1,342 +1,355 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class DeviceManager
|
||||
{
|
||||
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
|
||||
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
|
||||
//public static List<Device> Devices { get { return _Devices; } }
|
||||
//static List<Device> _Devices = new List<Device>();
|
||||
|
||||
static readonly Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of all the devices in a list
|
||||
/// </summary>
|
||||
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
|
||||
|
||||
public static bool AddDeviceEnabled;
|
||||
|
||||
public static void Initialize(CrestronControlSystem cs)
|
||||
{
|
||||
AddDeviceEnabled = true;
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate steps on all Device class items
|
||||
/// </summary>
|
||||
public static void ActivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PreActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).Activate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PostActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate on all Device class items
|
||||
/// </summary>
|
||||
public static void DeactivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
foreach (var d in Devices.Values.OfType<Device>())
|
||||
{
|
||||
d.Deactivate();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
//static void ListMethods(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if(dev != null)
|
||||
// {
|
||||
// var type = dev.GetType().GetCType();
|
||||
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
|
||||
// var sb = new StringBuilder();
|
||||
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
|
||||
// foreach (var m in methods)
|
||||
// {
|
||||
// sb.Append(string.Format("{0}(", m.Name));
|
||||
// var pars = m.GetParameters();
|
||||
// foreach (var p in pars)
|
||||
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
|
||||
// sb.AppendLine(")");
|
||||
// }
|
||||
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
// }
|
||||
//}
|
||||
|
||||
private static void ListDevices(string s)
|
||||
{
|
||||
Debug.Console(0, "{0} Devices registered with Device Manager:", Devices.Count);
|
||||
var sorted = Devices.Values.ToList();
|
||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||
|
||||
foreach (var d in sorted)
|
||||
{
|
||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||
Debug.Console(0, " [{0}] {1}", d.Key, name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ListDeviceFeedbacks(string devKey)
|
||||
{
|
||||
var dev = GetDeviceForKey(devKey);
|
||||
if (dev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
return;
|
||||
}
|
||||
var statusDev = dev as IHasFeedback;
|
||||
if (statusDev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
|
||||
return;
|
||||
}
|
||||
statusDev.DumpFeedbacksToConsole(true);
|
||||
}
|
||||
|
||||
//static void ListDeviceCommands(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if (dev == null)
|
||||
// {
|
||||
// Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
// return;
|
||||
// }
|
||||
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
|
||||
//}
|
||||
|
||||
private static void ListDeviceCommStatuses(string input)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
|
||||
{
|
||||
sb.Append(string.Format("{0}: {1}\r", dev,
|
||||
dev.CommunicationMonitor.Status));
|
||||
}
|
||||
CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
//static void DoDeviceCommand(string command)
|
||||
//{
|
||||
// Debug.Console(0, "Not yet implemented. Stay tuned");
|
||||
//}
|
||||
|
||||
public static void AddDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
// Check for device with same key
|
||||
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
|
||||
////// If it exists, remove or warn??
|
||||
//if (existingDevice != null)
|
||||
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
{
|
||||
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
|
||||
return;
|
||||
}
|
||||
Devices.Add(newDev.Key, newDev);
|
||||
//if (!(_Devices.Contains(newDev)))
|
||||
// _Devices.Add(newDev);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var dev in devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
Devices.Add(dev.Key, dev);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
|
||||
dev.Key, ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
if (newDev == null)
|
||||
return;
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
Devices.Remove(newDev.Key);
|
||||
//if (_Devices.Contains(newDev))
|
||||
// _Devices.Remove(newDev);
|
||||
else
|
||||
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetDeviceKeys()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Keys;
|
||||
}
|
||||
|
||||
public static IEnumerable<IKeyed> GetDevices()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Values;
|
||||
}
|
||||
|
||||
public static IKeyed GetDeviceForKey(string key)
|
||||
{
|
||||
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
if (key != null && Devices.ContainsKey(key))
|
||||
return Devices[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Console handler that simulates com port data receive
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SimulateComReceiveOnDevice(string s)
|
||||
{
|
||||
// devcomsim:1 xyzabc
|
||||
var match = Regex.Match(s, @"(\S*)\s*(.*)");
|
||||
if (match.Groups.Count < 3)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
|
||||
|
||||
var com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
|
||||
if (com == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
|
||||
return;
|
||||
}
|
||||
com.SimulateReceive(match.Groups[2].Value);
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class DeviceManager
|
||||
{
|
||||
public static event EventHandler<EventArgs> AllDevicesActivated;
|
||||
|
||||
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
|
||||
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
|
||||
//public static List<Device> Devices { get { return _Devices; } }
|
||||
//static List<Device> _Devices = new List<Device>();
|
||||
|
||||
static readonly Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of all the devices in a list
|
||||
/// </summary>
|
||||
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
|
||||
|
||||
public static bool AddDeviceEnabled;
|
||||
|
||||
public static void Initialize(CrestronControlSystem cs)
|
||||
{
|
||||
AddDeviceEnabled = true;
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate steps on all Device class items
|
||||
/// </summary>
|
||||
public static void ActivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PreActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).Activate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PostActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
OnAllDevicesActivated();
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnAllDevicesActivated()
|
||||
{
|
||||
var handler = AllDevicesActivated;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(null, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate on all Device class items
|
||||
/// </summary>
|
||||
public static void DeactivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
foreach (var d in Devices.Values.OfType<Device>())
|
||||
{
|
||||
d.Deactivate();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
//static void ListMethods(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if(dev != null)
|
||||
// {
|
||||
// var type = dev.GetType().GetCType();
|
||||
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
|
||||
// var sb = new StringBuilder();
|
||||
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
|
||||
// foreach (var m in methods)
|
||||
// {
|
||||
// sb.Append(string.Format("{0}(", m.Name));
|
||||
// var pars = m.GetParameters();
|
||||
// foreach (var p in pars)
|
||||
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
|
||||
// sb.AppendLine(")");
|
||||
// }
|
||||
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
// }
|
||||
//}
|
||||
|
||||
private static void ListDevices(string s)
|
||||
{
|
||||
Debug.Console(0, "{0} Devices registered with Device Manager:", Devices.Count);
|
||||
var sorted = Devices.Values.ToList();
|
||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||
|
||||
foreach (var d in sorted)
|
||||
{
|
||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||
Debug.Console(0, " [{0}] {1}", d.Key, name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ListDeviceFeedbacks(string devKey)
|
||||
{
|
||||
var dev = GetDeviceForKey(devKey);
|
||||
if (dev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
return;
|
||||
}
|
||||
var statusDev = dev as IHasFeedback;
|
||||
if (statusDev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
|
||||
return;
|
||||
}
|
||||
statusDev.DumpFeedbacksToConsole(true);
|
||||
}
|
||||
|
||||
//static void ListDeviceCommands(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if (dev == null)
|
||||
// {
|
||||
// Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
// return;
|
||||
// }
|
||||
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
|
||||
//}
|
||||
|
||||
private static void ListDeviceCommStatuses(string input)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
|
||||
{
|
||||
sb.Append(string.Format("{0}: {1}\r", dev,
|
||||
dev.CommunicationMonitor.Status));
|
||||
}
|
||||
CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
//static void DoDeviceCommand(string command)
|
||||
//{
|
||||
// Debug.Console(0, "Not yet implemented. Stay tuned");
|
||||
//}
|
||||
|
||||
public static void AddDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
// Check for device with same key
|
||||
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
|
||||
////// If it exists, remove or warn??
|
||||
//if (existingDevice != null)
|
||||
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
{
|
||||
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
|
||||
return;
|
||||
}
|
||||
Devices.Add(newDev.Key, newDev);
|
||||
//if (!(_Devices.Contains(newDev)))
|
||||
// _Devices.Add(newDev);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var dev in devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
Devices.Add(dev.Key, dev);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
|
||||
dev.Key, ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
if (newDev == null)
|
||||
return;
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
Devices.Remove(newDev.Key);
|
||||
//if (_Devices.Contains(newDev))
|
||||
// _Devices.Remove(newDev);
|
||||
else
|
||||
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetDeviceKeys()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Keys;
|
||||
}
|
||||
|
||||
public static IEnumerable<IKeyed> GetDevices()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Values;
|
||||
}
|
||||
|
||||
public static IKeyed GetDeviceForKey(string key)
|
||||
{
|
||||
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
if (key != null && Devices.ContainsKey(key))
|
||||
return Devices[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Console handler that simulates com port data receive
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SimulateComReceiveOnDevice(string s)
|
||||
{
|
||||
// devcomsim:1 xyzabc
|
||||
var match = Regex.Match(s, @"(\S*)\s*(.*)");
|
||||
if (match.Groups.Count < 3)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
|
||||
|
||||
var com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
|
||||
if (com == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
|
||||
return;
|
||||
}
|
||||
com.SimulateReceive(match.Groups[2].Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -347,9 +360,9 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
var device = GetDeviceForKey(s);
|
||||
|
||||
if (device == null) return;
|
||||
var inputPorts = (device as IRoutingInputsOutputs).InputPorts;
|
||||
var outputPorts = (device as IRoutingInputsOutputs).OutputPorts;
|
||||
if (device == null) return;
|
||||
var inputPorts = ((device as IRoutingInputs) != null) ? (device as IRoutingInputs).InputPorts : null;
|
||||
var outputPorts = ((device as IRoutingOutputs) != null) ? (device as IRoutingOutputs).OutputPorts : null;
|
||||
if (inputPorts != null)
|
||||
{
|
||||
Debug.Console(0, "Device {0} has {1} Input Ports:", s, inputPorts.Count);
|
||||
@@ -366,82 +379,82 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, "{0}", routingOutputPort.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to set the debug level of a device
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SetDeviceStreamDebugging(string s)
|
||||
{
|
||||
var args = s.Split(' ');
|
||||
|
||||
var deviceKey = args[0];
|
||||
var setting = args[1];
|
||||
|
||||
var timeout= String.Empty;
|
||||
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
timeout = args[2];
|
||||
}
|
||||
|
||||
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
|
||||
try
|
||||
{
|
||||
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var min = Convert.ToUInt32(timeout);
|
||||
|
||||
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets stream debugging settings to off for all devices
|
||||
/// </summary>
|
||||
public static void DisableAllDeviceStreamDebugging()
|
||||
{
|
||||
foreach (var device in AllDevices)
|
||||
{
|
||||
var streamDevice = device as IStreamDebugging;
|
||||
|
||||
if (streamDevice != null)
|
||||
{
|
||||
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to set the debug level of a device
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SetDeviceStreamDebugging(string s)
|
||||
{
|
||||
var args = s.Split(' ');
|
||||
|
||||
var deviceKey = args[0];
|
||||
var setting = args[1];
|
||||
|
||||
var timeout= String.Empty;
|
||||
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
timeout = args[2];
|
||||
}
|
||||
|
||||
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
|
||||
try
|
||||
{
|
||||
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var min = Convert.ToUInt32(timeout);
|
||||
|
||||
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets stream debugging settings to off for all devices
|
||||
/// </summary>
|
||||
public static void DisableAllDeviceStreamDebugging()
|
||||
{
|
||||
foreach (var device in AllDevices)
|
||||
{
|
||||
var streamDevice = device as IStreamDebugging;
|
||||
|
||||
if (streamDevice != null)
|
||||
{
|
||||
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Devices
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
public class GenericIrController: EssentialsBridgeableDevice
|
||||
{
|
||||
|
||||
@@ -20,10 +20,13 @@ namespace PepperDash.Essentials.Core
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
[Obsolete("This property will be removed in version 2.0.0")]
|
||||
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
protected Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get { return () => _IsCoolingDown; }
|
||||
@@ -33,7 +36,7 @@ namespace PepperDash.Essentials.Core
|
||||
get { return () => _IsWarmingUp; }
|
||||
}
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
@@ -43,11 +46,14 @@ namespace PepperDash.Essentials.Core
|
||||
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
|
||||
DeviceManager.AddDevice(IrPort);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += (o, a) => {
|
||||
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||
if (_PowerIsOn) StartWarmingTimer();
|
||||
else StartCoolingTimer();
|
||||
};
|
||||
PowerIsOnFeedback = new BoolFeedback(PowerIsOnFeedbackFunc);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||
if (_PowerIsOn) StartWarmingTimer();
|
||||
else StartCoolingTimer();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
|
||||
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
|
||||
|
||||
@@ -110,21 +116,21 @@ namespace PepperDash.Essentials.Core
|
||||
public override void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||
_PowerIsOn = true;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
_PowerIsOn = true;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public override void PowerOff()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,131 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
public uint WarmupTime { get; set; }
|
||||
public uint CooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||
/// by concrete sub-classes
|
||||
/// </summary>
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||
|
||||
|
||||
protected CTimer WarmupTimer;
|
||||
protected CTimer CooldownTimer;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void PowerOn();
|
||||
public abstract void PowerOff();
|
||||
public abstract void PowerToggle();
|
||||
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
PowerIsOnFeedback,
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
var inputNumber = 0;
|
||||
var inputKeys = new List<string>();
|
||||
|
||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IPower
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
[Obsolete("This property will be removed in version 2.0.0")]
|
||||
public abstract BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
public uint WarmupTime { get; set; }
|
||||
public uint CooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||
/// by concrete sub-classes
|
||||
/// </summary>
|
||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||
|
||||
|
||||
protected CTimer WarmupTimer;
|
||||
protected CTimer CooldownTimer;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
}
|
||||
|
||||
public abstract void PowerOn();
|
||||
public abstract void PowerOff();
|
||||
public abstract void PowerToggle();
|
||||
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
var inputNumber = 0;
|
||||
var inputKeys = new List<string>();
|
||||
|
||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
@@ -137,163 +124,198 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||
if (commMonitor != null)
|
||||
{
|
||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
}
|
||||
|
||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
||||
|
||||
// Two way feedbacks
|
||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
||||
|
||||
if (twoWayDisplay != null)
|
||||
{
|
||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
|
||||
|
||||
|
||||
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
displayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!a.BoolValue)
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
|
||||
// PowerOn
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOn();
|
||||
});
|
||||
|
||||
|
||||
displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
|
||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
||||
{
|
||||
if (i < joinMap.InputNamesOffset.JoinSpan)
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[i].Key);
|
||||
var tempKey = inputKeys.ElementAt(i);
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
|
||||
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
|
||||
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
|
||||
}
|
||||
else
|
||||
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
|
||||
}
|
||||
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
displayDevice.PowerOff();
|
||||
inputNumber = 0;
|
||||
}
|
||||
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
|
||||
{
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
|
||||
inputNumber = a;
|
||||
}
|
||||
else if (a == 102)
|
||||
{
|
||||
displayDevice.PowerToggle();
|
||||
|
||||
}
|
||||
if (twoWayDisplay != null)
|
||||
inputNumberFeedback.FireUpdate();
|
||||
});
|
||||
|
||||
|
||||
var volumeDisplay = displayDevice as IBasicVolumeControls;
|
||||
if (volumeDisplay == null) return;
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
|
||||
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
|
||||
|
||||
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (volumeDisplayWithFeedback == null) return;
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
|
||||
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
|
||||
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class TwoWayDisplayBase : DisplayBase
|
||||
{
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _DefaultDisplay;
|
||||
}
|
||||
}
|
||||
static MockDisplay _DefaultDisplay;
|
||||
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||
if (commMonitor != null)
|
||||
{
|
||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
}
|
||||
|
||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
||||
|
||||
// Two way feedbacks
|
||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
||||
|
||||
if (twoWayDisplay != null)
|
||||
{
|
||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
|
||||
|
||||
|
||||
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
|
||||
if (twoWayDisplayDevice != null)
|
||||
{
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!a.BoolValue)
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
}
|
||||
|
||||
// PowerOn
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOn();
|
||||
});
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
||||
{
|
||||
if (i < joinMap.InputNamesOffset.JoinSpan)
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[i].Key);
|
||||
var tempKey = inputKeys.ElementAt(i);
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
|
||||
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
|
||||
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
|
||||
}
|
||||
else
|
||||
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
|
||||
}
|
||||
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
displayDevice.PowerOff();
|
||||
inputNumber = 0;
|
||||
}
|
||||
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
|
||||
{
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
|
||||
inputNumber = a;
|
||||
}
|
||||
else if (a == 102)
|
||||
{
|
||||
displayDevice.PowerToggle();
|
||||
|
||||
}
|
||||
if (twoWayDisplay != null)
|
||||
inputNumberFeedback.FireUpdate();
|
||||
});
|
||||
|
||||
|
||||
var volumeDisplay = displayDevice as IBasicVolumeControls;
|
||||
if (volumeDisplay == null) return;
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
|
||||
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
|
||||
|
||||
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (volumeDisplayWithFeedback == null) return;
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
|
||||
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
|
||||
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||
{
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
|
||||
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _DefaultDisplay;
|
||||
}
|
||||
}
|
||||
static MockDisplay _DefaultDisplay;
|
||||
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,13 +67,13 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns></returns>
|
||||
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
|
||||
}
|
||||
|
||||
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
|
||||
if(FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
|
||||
@@ -3,8 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class IsReadyEventArgs : EventArgs
|
||||
{
|
||||
@@ -16,6 +17,27 @@ namespace PepperDash_Essentials_Core
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHasReady
|
||||
{
|
||||
event EventHandler<IsReadyEventArgs> IsReadyEvent;
|
||||
bool IsReady { get; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core")]
|
||||
public class IsReadyEventArgs : EventArgs
|
||||
{
|
||||
public bool IsReady { get; set; }
|
||||
|
||||
public IsReadyEventArgs(bool data)
|
||||
{
|
||||
IsReady = data;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use PepperDash.Essentials.Core")]
|
||||
public interface IHasReady
|
||||
{
|
||||
event EventHandler<IsReadyEventArgs> IsReadyEvent;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoomFusionRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
|
||||
// Processor Attributes
|
||||
[JoinName("ProcessorIp1")]
|
||||
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorIp2")]
|
||||
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorGateway")]
|
||||
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
|
||||
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorHostname")]
|
||||
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
|
||||
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDomain")]
|
||||
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
|
||||
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDns1")]
|
||||
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDns2")]
|
||||
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorMac1")]
|
||||
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorMac2")]
|
||||
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorNetMask1")]
|
||||
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorNetMask2")]
|
||||
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorFirmware")]
|
||||
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
|
||||
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProgramNameStart")]
|
||||
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
|
||||
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorReboot")]
|
||||
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
|
||||
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
// Volume Controls
|
||||
[JoinName("VolumeFader1")]
|
||||
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
|
||||
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
|
||||
|
||||
// Codec Info
|
||||
[JoinName("VcCodecInCall")]
|
||||
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
|
||||
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VcCodecOnline")]
|
||||
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
|
||||
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VcCodecIpAddress")]
|
||||
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
|
||||
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("VcCodecIpPort")]
|
||||
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
|
||||
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
// Source Attributes
|
||||
[JoinName("Display1CurrentSourceName")]
|
||||
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
|
||||
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
|
||||
// Device Online Status
|
||||
[JoinName("TouchpanelOnlineStart")]
|
||||
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
|
||||
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("XpanelOnlineStart")]
|
||||
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
|
||||
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("DisplayOnlineStart")]
|
||||
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
|
||||
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1LaptopSourceStart")]
|
||||
public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
|
||||
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1DiscPlayerSourceStart")]
|
||||
public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
|
||||
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1SetTopBoxSourceStart")]
|
||||
public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
|
||||
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
// Display 1
|
||||
[JoinName("Display1Start")]
|
||||
public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(EssentialsHuddleSpaceRoomFusionRoomJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash_Essentials_Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
public static LicenseManager LicenseManager { get; set; }
|
||||
|
||||
public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the folder containing configuration files
|
||||
/// </summary>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using Activator = System.Activator;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
@@ -14,13 +17,17 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
public static class Scheduler
|
||||
{
|
||||
private static Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||
private static readonly Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||
|
||||
static Scheduler()
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(ListAllEventsForGroup, "ListEventsForGroup",
|
||||
"Lists all events for the given group", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -29,12 +36,26 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="groupName"></param>
|
||||
static void ClearEventsFromGroup(string groupName)
|
||||
{
|
||||
if (!EventGroups.ContainsKey(groupName))
|
||||
{
|
||||
Debug.Console(0,
|
||||
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
|
||||
groupName);
|
||||
return;
|
||||
}
|
||||
|
||||
var group = EventGroups[groupName];
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
group.ClearAllEvents();
|
||||
|
||||
Debug.Console(0, "[Scheduler]: All events deleted from group '{0}'", groupName);
|
||||
}
|
||||
else
|
||||
Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName);
|
||||
Debug.Console(0,
|
||||
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
|
||||
groupName);
|
||||
}
|
||||
|
||||
static void ListAllEventGroups(string command)
|
||||
@@ -46,10 +67,36 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
static void ListAllEventsForGroup(string args)
|
||||
{
|
||||
Debug.Console(0, "Getting events for group {0}...", args);
|
||||
|
||||
ScheduledEventGroup group;
|
||||
|
||||
if (!EventGroups.TryGetValue(args, out group))
|
||||
{
|
||||
Debug.Console(0, "Unabled to get event group for key {0}", args);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var evt in group.ScheduledEvents)
|
||||
{
|
||||
Debug.Console(0,
|
||||
@"
|
||||
****Event key {0}****
|
||||
Event date/time: {1}
|
||||
Persistent: {2}
|
||||
Acknowlegable: {3}
|
||||
Recurrence: {4}
|
||||
Recurrence Days: {5}
|
||||
********************", evt.Key, evt.Value.DateAndTime, evt.Value.Persistent, evt.Value.Acknowledgeable,
|
||||
evt.Value.Recurrence.Recurrence, evt.Value.Recurrence.RecurrenceDays);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the event group to the global list
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddEventGroup(ScheduledEventGroup eventGroup)
|
||||
{
|
||||
@@ -67,6 +114,13 @@ namespace PepperDash.Essentials.Core
|
||||
if(!EventGroups.ContainsKey(eventGroup.Name))
|
||||
EventGroups.Remove(eventGroup.Name);
|
||||
}
|
||||
|
||||
public static ScheduledEventGroup GetEventGroup(string key)
|
||||
{
|
||||
ScheduledEventGroup returnValue;
|
||||
|
||||
return EventGroups.TryGetValue(key, out returnValue) ? returnValue : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SchedulerUtilities
|
||||
@@ -135,5 +189,90 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
public static bool CheckEventTimeForMatch(ScheduledEvent evnt, DateTime time)
|
||||
{
|
||||
return evnt.DateAndTime.Hour == time.Hour && evnt.DateAndTime.Minute == time.Minute;
|
||||
}
|
||||
|
||||
public static bool CheckEventRecurrenceForMatch(ScheduledEvent evnt, ScheduledEventCommon.eWeekDays days)
|
||||
{
|
||||
return evnt.Recurrence.RecurrenceDays == days;
|
||||
}
|
||||
|
||||
public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to create event. Group is null");
|
||||
return;
|
||||
}
|
||||
var scheduledEvent = new ScheduledEvent(config.Key, group)
|
||||
{
|
||||
Acknowledgeable = config.Acknowledgeable,
|
||||
Persistent = config.Persistent
|
||||
};
|
||||
|
||||
scheduledEvent.UserCallBack += handler;
|
||||
|
||||
scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday);
|
||||
|
||||
var eventTime = DateTime.Parse(config.Time);
|
||||
|
||||
if (DateTime.Now > eventTime)
|
||||
{
|
||||
eventTime = eventTime.AddDays(1);
|
||||
}
|
||||
|
||||
Debug.Console(2, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek,
|
||||
config.Days);
|
||||
|
||||
var dayOfWeekConverted = ConvertDayOfWeek(eventTime);
|
||||
|
||||
Debug.Console(1, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted);
|
||||
|
||||
while (!dayOfWeekConverted.IsFlagSet(config.Days))
|
||||
{
|
||||
eventTime = eventTime.AddDays(1);
|
||||
|
||||
dayOfWeekConverted = ConvertDayOfWeek(eventTime);
|
||||
}
|
||||
|
||||
scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime);
|
||||
|
||||
scheduledEvent.Recurrence.Weekly(config.Days);
|
||||
|
||||
if (config.Enable)
|
||||
{
|
||||
scheduledEvent.Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduledEvent.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
private static ScheduledEventCommon.eWeekDays ConvertDayOfWeek(DateTime eventTime)
|
||||
{
|
||||
return (ScheduledEventCommon.eWeekDays) Enum.Parse(typeof(ScheduledEventCommon.eWeekDays), eventTime.DayOfWeek.ToString(), true);
|
||||
}
|
||||
|
||||
private static bool IsFlagSet<T>(this T value, T flag) where T : struct
|
||||
{
|
||||
CheckIsEnum<T>(true);
|
||||
|
||||
var lValue = Convert.ToInt64(value);
|
||||
var lFlag = Convert.ToInt64(flag);
|
||||
|
||||
return (lValue & lFlag) != 0;
|
||||
}
|
||||
|
||||
private static void CheckIsEnum<T>(bool withFlags)
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
|
||||
if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
|
||||
throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Interfaces
|
||||
{
|
||||
public interface ILogStrings : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a class that is capable of logging a string
|
||||
/// </summary>
|
||||
void SendToLog(IKeyed device, string logMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Interfaces
|
||||
{
|
||||
public interface ILogStringsWithLevel : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a class that is capable of logging a string with an int level
|
||||
/// </summary>
|
||||
void SendToLog(IKeyed device, Debug.ErrorLogLevel level,string logMessage);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
|
||||
|
||||
return joinMap;
|
||||
return joinMap.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,16 +45,33 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, JoinData> TryGetJoinMapAdvancedForDevice(string joinMapKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(joinMapKey))
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(joinMapKey))
|
||||
return null;
|
||||
|
||||
if (!ConfigReader.ConfigObject.JoinMaps.ContainsKey(joinMapKey))
|
||||
{
|
||||
Debug.Console(2, "No Join Map found in config with key: '{0}'", joinMapKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Console(2, "Attempting to load custom join map with key: {0}", joinMapKey);
|
||||
|
||||
var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
|
||||
|
||||
if (joinMapJToken == null)
|
||||
return null;
|
||||
|
||||
var joinMapData = joinMapJToken.ToObject<Dictionary<string, JoinData>>();
|
||||
|
||||
return joinMapData;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Error getting join map for key: '{0}'. Error: {1}", joinMapKey, e);
|
||||
return null;
|
||||
|
||||
var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
|
||||
|
||||
if (joinMapSerialzed == null) return null;
|
||||
|
||||
var joinMapData = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
|
||||
|
||||
return joinMapData;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -216,7 +233,10 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
|
||||
PrintJoinMapInfo();
|
||||
if (Debug.Level > 0)
|
||||
{
|
||||
PrintJoinMapInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -266,7 +286,7 @@ namespace PepperDash.Essentials.Core
|
||||
@"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'",
|
||||
join.Value.JoinNumber,
|
||||
join.Value.JoinSpan,
|
||||
String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label: join.Value.Metadata.Description,
|
||||
String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName,
|
||||
join.Value.Metadata.JoinType.ToString(),
|
||||
join.Value.Metadata.JoinCapabilities.ToString());
|
||||
}
|
||||
@@ -288,7 +308,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
|
||||
Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +347,10 @@ namespace PepperDash.Essentials.Core
|
||||
None = 0,
|
||||
ToSIMPL = 1,
|
||||
FromSIMPL = 2,
|
||||
ToFromSIMPL = ToSIMPL | FromSIMPL
|
||||
ToFromSIMPL = ToSIMPL | FromSIMPL,
|
||||
ToFusion = 4,
|
||||
FromFusion = 8,
|
||||
ToFromFusion = ToFusion | FromFusion,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -340,7 +363,7 @@ namespace PepperDash.Essentials.Core
|
||||
DigitalAnalog = Digital | Analog,
|
||||
DigitalSerial = Digital | Serial,
|
||||
AnalogSerial = Analog | Serial,
|
||||
DigitalAnalogSerial = Digital | Analog | Serial
|
||||
DigitalAnalogSerial = Digital | Analog | Serial,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -394,7 +417,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data describing the join. Can be
|
||||
/// Data describing the join. Can be overridden from configuratino
|
||||
/// </summary>
|
||||
public class JoinData
|
||||
{
|
||||
@@ -408,6 +431,11 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
[JsonProperty("joinSpan")]
|
||||
public uint JoinSpan { get; set; }
|
||||
/// <summary>
|
||||
/// Fusion Attribute Name (optional)
|
||||
/// </summary>
|
||||
[JsonProperty("attributeName")]
|
||||
public string AttributeName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -419,6 +447,10 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private JoinData _data;
|
||||
public JoinMetadata Metadata { get; set; }
|
||||
/// <summary>
|
||||
/// To store some future information as you please
|
||||
/// </summary>
|
||||
public object UserObject { get; private set; }
|
||||
|
||||
public JoinDataComplete(JoinData data, JoinMetadata metadata)
|
||||
{
|
||||
@@ -449,6 +481,11 @@ namespace PepperDash.Essentials.Core
|
||||
get { return _data.JoinSpan; }
|
||||
}
|
||||
|
||||
public string AttributeName
|
||||
{
|
||||
get { return _data.AttributeName; }
|
||||
}
|
||||
|
||||
public void SetCustomJoinData(JoinData customJoinData)
|
||||
{
|
||||
_data = customJoinData;
|
||||
|
||||
@@ -88,8 +88,12 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
else
|
||||
Debug.Console(0, this, "Unable to add Red LED device");
|
||||
|
||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
};
|
||||
|
||||
AddPostActivationAction(() => {
|
||||
CheckPrivacyMode();
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||
});
|
||||
|
||||
@@ -64,30 +64,34 @@ namespace PepperDash.Essentials.Core
|
||||
initialStatus = MonitorStatus.InWarning;
|
||||
prefix = "2:";
|
||||
}
|
||||
else if (InWarning.Count() > 0)
|
||||
else if (IsOk.Count() > 0)
|
||||
initialStatus = MonitorStatus.IsOk;
|
||||
else
|
||||
initialStatus = MonitorStatus.StatusUnknown;
|
||||
|
||||
// Build the error message string
|
||||
if (InError.Count() > 0 || InWarning.Count() > 0)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
if (InError.Count() > 0)
|
||||
{
|
||||
// Do string splits and joins
|
||||
sb.Append(string.Format("{0} Errors:", InError.Count()));
|
||||
foreach (var mon in InError)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
if (InWarning.Count() > 0)
|
||||
{
|
||||
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
|
||||
foreach (var mon in InWarning)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
Message = sb.ToString();
|
||||
}
|
||||
if (InError.Count() > 0 || InWarning.Count() > 0)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
if (InError.Count() > 0)
|
||||
{
|
||||
// Do string splits and joins
|
||||
sb.Append(string.Format("{0} Errors:", InError.Count()));
|
||||
foreach (var mon in InError)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
if (InWarning.Count() > 0)
|
||||
{
|
||||
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
|
||||
foreach (var mon in InWarning)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
Message = sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
Message = "Room Ok.";
|
||||
}
|
||||
|
||||
// Want to fire even if status doesn't change because the message may.
|
||||
Status = initialStatus;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,460 +1,539 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
|
||||
public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
|
||||
{
|
||||
public GlsOccupancySensorBase OccSensor { get; private set; }
|
||||
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
|
||||
[ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0}")]
|
||||
public abstract class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
|
||||
{
|
||||
public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
|
||||
protected GlsOccupancySensorBase OccSensor;
|
||||
|
||||
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
|
||||
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback RawOccupancyFeedback { get; private set; }
|
||||
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
|
||||
public BoolFeedback RawOccupancyFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
|
||||
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
|
||||
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
|
||||
|
||||
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
|
||||
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
|
||||
|
||||
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
|
||||
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
|
||||
|
||||
public IntFeedback CurrentTimeoutFeedback { get; private set; }
|
||||
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
|
||||
|
||||
public IntFeedback LocalTimoutFeedback { get; private set; }
|
||||
public IntFeedback CurrentTimeoutFeedback { get; private set; }
|
||||
|
||||
public IntFeedback InternalPhotoSensorValue { get; set; }
|
||||
public IntFeedback LocalTimoutFeedback { get; private set; }
|
||||
|
||||
public IntFeedback ExternalPhotoSensorValue { get; set; }
|
||||
public IntFeedback InternalPhotoSensorValue { get; set; }
|
||||
|
||||
// Debug properties
|
||||
public bool InTestMode { get; private set; }
|
||||
public IntFeedback ExternalPhotoSensorValue { get; set; }
|
||||
|
||||
public bool TestRoomIsOccupiedFeedback { get; private set; }
|
||||
// Debug properties
|
||||
public bool InTestMode { get; private set; }
|
||||
|
||||
public Func<bool> RoomIsOccupiedFeedbackFunc
|
||||
public bool TestRoomIsOccupiedFeedback { get; private set; }
|
||||
|
||||
public Func<bool> RoomIsOccupiedFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
|
||||
protected GlsOccupancySensorBaseController(string key, DeviceConfig config)
|
||||
: this(key, config.Name, config)
|
||||
{
|
||||
}
|
||||
|
||||
protected GlsOccupancySensorBaseController(string key, string name, DeviceConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
get
|
||||
|
||||
var props = config.Properties.ToObject<GlsOccupancySensorPropertiesConfig>();
|
||||
|
||||
if (props != null)
|
||||
{
|
||||
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
|
||||
public GlsOccupancySensorBaseController(string key, Func<DeviceConfig, GlsOccupancySensorBase> preActivationFunc,
|
||||
DeviceConfig config)
|
||||
: base(key, config.Name)
|
||||
{
|
||||
|
||||
|
||||
AddPreActivationAction(() =>
|
||||
{
|
||||
OccSensor = preActivationFunc(config);
|
||||
|
||||
RegisterCrestronGenericBase(OccSensor);
|
||||
|
||||
RegisterGlsOdtSensorBaseController(OccSensor);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {}
|
||||
|
||||
protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor)
|
||||
{
|
||||
OccSensor = occSensor;
|
||||
|
||||
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
|
||||
|
||||
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
|
||||
|
||||
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
|
||||
|
||||
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
|
||||
|
||||
PirSensitivityInVacantStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
PirSensitivityInOccupiedStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
|
||||
|
||||
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
|
||||
|
||||
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
|
||||
|
||||
GraceOccupancyDetectedFeedback =
|
||||
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
|
||||
|
||||
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
|
||||
|
||||
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
OccSensor.BaseEvent += OccSensor_BaseEvent;
|
||||
|
||||
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
|
||||
PirSensorEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
|
||||
LedFlashEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
|
||||
ShortTimeoutEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
|
||||
PirSensitivityInOccupiedStateFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
|
||||
PirSensitivityInVacantStateFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId:
|
||||
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
|
||||
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
|
||||
CurrentTimeoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
|
||||
LocalTimoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
|
||||
GraceOccupancyDetectedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
|
||||
RawOccupancyFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
|
||||
InternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
|
||||
ExternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTestMode(bool mode)
|
||||
{
|
||||
InTestMode = mode;
|
||||
|
||||
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
|
||||
}
|
||||
|
||||
public void SetTestOccupiedState(bool state)
|
||||
{
|
||||
if (!InTestMode)
|
||||
Debug.Console(1, "Mock mode not enabled");
|
||||
else
|
||||
{
|
||||
TestRoomIsOccupiedFeedback = state;
|
||||
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the PIR sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetPirEnable(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
OccSensor.EnablePir.BoolValue = state;
|
||||
OccSensor.DisablePir.BoolValue = !state;
|
||||
PropertiesConfig = props;
|
||||
}
|
||||
else
|
||||
{
|
||||
OccSensor.EnablePir.BoolValue = state;
|
||||
OccSensor.DisablePir.BoolValue = !state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the LED Flash
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetLedFlashEnable(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
OccSensor.EnableLedFlash.BoolValue = state;
|
||||
OccSensor.DisableLedFlash.BoolValue = !state;
|
||||
}
|
||||
else
|
||||
{
|
||||
OccSensor.EnableLedFlash.BoolValue = state;
|
||||
OccSensor.DisableLedFlash.BoolValue = !state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables short timeout based on state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetShortTimeoutState(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
OccSensor.EnableShortTimeout.BoolValue = state;
|
||||
OccSensor.DisableShortTimeout.BoolValue = !state;
|
||||
}
|
||||
else
|
||||
{
|
||||
OccSensor.EnableShortTimeout.BoolValue = state;
|
||||
OccSensor.DisableShortTimeout.BoolValue = !state;
|
||||
}
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void ForceOccupied()
|
||||
{
|
||||
OccSensor.ForceOccupied.BoolValue = true;
|
||||
}
|
||||
|
||||
public void ForceVacant()
|
||||
{
|
||||
OccSensor.ForceVacant.BoolValue = true;
|
||||
}
|
||||
|
||||
public void EnableRawStates(bool state)
|
||||
{
|
||||
OccSensor.EnableRawStates.BoolValue = state;
|
||||
}
|
||||
|
||||
public void SetRemoteTimeout(ushort time)
|
||||
{
|
||||
OccSensor.RemoteTimeout.UShortValue = time;
|
||||
}
|
||||
|
||||
public void SetInternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
public void SetExternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig");
|
||||
}
|
||||
|
||||
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
#region Single and Dual Sensor Stuff
|
||||
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
|
||||
trilist.OnlineStatusChange += (d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
}
|
||||
};
|
||||
OccSensor.OnlineStatusChange += (o, a) =>
|
||||
{
|
||||
if (a.DeviceOnLine)
|
||||
{
|
||||
ApplySettingsToSensorFromConfig();
|
||||
}
|
||||
};
|
||||
|
||||
// Occupied status
|
||||
trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
|
||||
trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
|
||||
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
|
||||
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
|
||||
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
|
||||
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
|
||||
if (OccSensor.IsOnline)
|
||||
{
|
||||
ApplySettingsToSensorFromConfig();
|
||||
|
||||
// Timouts
|
||||
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
|
||||
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
|
||||
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
|
||||
|
||||
// LED Flash
|
||||
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
|
||||
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
|
||||
|
||||
// Short Timeout
|
||||
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
|
||||
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
|
||||
|
||||
// PIR Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
|
||||
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState);
|
||||
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState);
|
||||
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
|
||||
#endregion
|
||||
|
||||
#region Dual Technology Sensor Stuff
|
||||
var odtOccController = occController as GlsOdtOccupancySensorController;
|
||||
|
||||
if (odtOccController == null) return;
|
||||
// OR When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
|
||||
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
|
||||
|
||||
// AND When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
|
||||
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
|
||||
|
||||
// Ultrasonic A Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
|
||||
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
|
||||
|
||||
// Ultrasonic B Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
|
||||
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState);
|
||||
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState);
|
||||
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
|
||||
|
||||
//Sensor Raw States
|
||||
odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
|
||||
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
|
||||
|
||||
#endregion
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
|
||||
/// <summary>
|
||||
/// Applies any sensor settings defined in config
|
||||
/// </summary>
|
||||
protected virtual void ApplySettingsToSensorFromConfig()
|
||||
{
|
||||
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
Debug.Console(1, this, "Attempting to apply settings to sensor from config");
|
||||
|
||||
if (PropertiesConfig.EnablePir != null)
|
||||
{
|
||||
Debug.Console(1, this, "EnablePir found, attempting to set value from config");
|
||||
SetPirEnable((bool)PropertiesConfig.EnablePir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "EnablePir null, no value specified in config");
|
||||
}
|
||||
|
||||
if (PropertiesConfig.EnableLedFlash != null)
|
||||
{
|
||||
Debug.Console(1, this, "EnableLedFlash found, attempting to set value from config");
|
||||
SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.RemoteTimeout != null)
|
||||
{
|
||||
Debug.Console(1, this, "RemoteTimeout found, attempting to set value from config");
|
||||
SetRemoteTimeout((ushort)PropertiesConfig.RemoteTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "RemoteTimeout null, no value specified in config");
|
||||
}
|
||||
|
||||
if (PropertiesConfig.ShortTimeoutState != null)
|
||||
{
|
||||
SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.EnableRawStates != null)
|
||||
{
|
||||
EnableRawStates((bool)PropertiesConfig.EnableRawStates);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.InternalPhotoSensorMinChange != null)
|
||||
{
|
||||
SetInternalPhotoSensorMinChange((ushort)PropertiesConfig.InternalPhotoSensorMinChange);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.ExternalPhotoSensorMinChange != null)
|
||||
{
|
||||
SetExternalPhotoSensorMinChange((ushort)PropertiesConfig.ExternalPhotoSensorMinChange);
|
||||
}
|
||||
}
|
||||
|
||||
#region PreActivation
|
||||
protected void RegisterGlsOccupancySensorBaseController(GlsOccupancySensorBase occSensor)
|
||||
{
|
||||
OccSensor = occSensor;
|
||||
|
||||
private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc)
|
||||
{
|
||||
var control = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var cresnetId = control.CresnetIdInt;
|
||||
var branchId = control.ControlPortNumber;
|
||||
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
|
||||
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
|
||||
|
||||
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
|
||||
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
|
||||
|
||||
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
|
||||
|
||||
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
|
||||
|
||||
PirSensitivityInVacantStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
PirSensitivityInOccupiedStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
|
||||
|
||||
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
|
||||
|
||||
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
|
||||
|
||||
GraceOccupancyDetectedFeedback =
|
||||
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
|
||||
|
||||
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
|
||||
|
||||
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
OccSensor.BaseEvent += OccSensor_BaseEvent;
|
||||
|
||||
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
|
||||
PirSensorEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
|
||||
LedFlashEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
|
||||
ShortTimeoutEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
|
||||
PirSensitivityInOccupiedStateFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
|
||||
PirSensitivityInVacantStateFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.RoomVacantFeedbackEventId:
|
||||
case GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
|
||||
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
|
||||
CurrentTimeoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
|
||||
LocalTimoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
|
||||
GraceOccupancyDetectedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
|
||||
RawOccupancyFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
|
||||
InternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
|
||||
ExternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTestMode(bool mode)
|
||||
{
|
||||
InTestMode = mode;
|
||||
|
||||
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
|
||||
}
|
||||
|
||||
public void SetTestOccupiedState(bool state)
|
||||
{
|
||||
if (!InTestMode)
|
||||
Debug.Console(1, "Mock mode not enabled");
|
||||
else
|
||||
{
|
||||
TestRoomIsOccupiedFeedback = state;
|
||||
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the PIR sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetPirEnable(bool state)
|
||||
{
|
||||
Debug.Console(1, this, "Setting EnablePir to: {0}", state);
|
||||
|
||||
OccSensor.EnablePir.BoolValue = state;
|
||||
OccSensor.DisablePir.BoolValue = !state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the LED Flash
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetLedFlashEnable(bool state)
|
||||
{
|
||||
OccSensor.EnableLedFlash.BoolValue = state;
|
||||
OccSensor.DisableLedFlash.BoolValue = !state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables short timeout based on state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetShortTimeoutState(bool state)
|
||||
{
|
||||
OccSensor.EnableShortTimeout.BoolValue = state;
|
||||
OccSensor.DisableShortTimeout.BoolValue = !state;
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulse ForceOccupied on the sensor for .5 seconds
|
||||
/// </summary>
|
||||
public void ForceOccupied()
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
ForceOccupied(true);
|
||||
CrestronEnvironment.Sleep(500);
|
||||
ForceOccupied(false);
|
||||
});
|
||||
}
|
||||
|
||||
public void ForceOccupied(bool value)
|
||||
{
|
||||
OccSensor.ForceOccupied.BoolValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulse ForceVacant on the sensor for .5 seconds
|
||||
/// </summary>
|
||||
public void ForceVacant()
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
|
||||
return new GlsOirCCn(cresnetId, Global.ControlSystem);
|
||||
}
|
||||
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
|
||||
ForceVacant(true);
|
||||
CrestronEnvironment.Sleep(500);
|
||||
ForceVacant(false);
|
||||
});
|
||||
}
|
||||
|
||||
if (cresnetBridge != null)
|
||||
{
|
||||
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
|
||||
return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
|
||||
}
|
||||
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
public void ForceVacant(bool value)
|
||||
{
|
||||
OccSensor.ForceVacant.BoolValue = value;
|
||||
}
|
||||
|
||||
public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<GlsOccupancySensorBaseController>
|
||||
{
|
||||
public GlsOccupancySensorBaseControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "glsoirccn" };
|
||||
}
|
||||
public void EnableRawStates(bool state)
|
||||
{
|
||||
OccSensor.EnableRawStates.BoolValue = state;
|
||||
}
|
||||
|
||||
public void SetRemoteTimeout(ushort time)
|
||||
{
|
||||
Debug.Console(1, this, "Setting RemoteTimout to: {0}", time);
|
||||
|
||||
OccSensor.RemoteTimeout.UShortValue = time;
|
||||
}
|
||||
|
||||
public void SetInternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
public void SetExternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to print current occ settings to console.
|
||||
/// </summary>
|
||||
public virtual void GetSettings()
|
||||
{
|
||||
var dash = new string('*', 50);
|
||||
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
|
||||
|
||||
Debug.Console(0, this, "Vacancy Detected: {0}",
|
||||
OccSensor.VacancyDetectedFeedback.BoolValue);
|
||||
|
||||
Debug.Console(0, this, "Timeout Current: {0} | Local: {1}",
|
||||
OccSensor.CurrentTimeoutFeedback.UShortValue,
|
||||
OccSensor.LocalTimeoutFeedback.UShortValue);
|
||||
|
||||
Debug.Console(0, this, "Short Timeout Enabled: {0}",
|
||||
OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
|
||||
|
||||
Debug.Console(0, this, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}",
|
||||
OccSensor.PirEnabledFeedback.BoolValue,
|
||||
OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue,
|
||||
OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
|
||||
}
|
||||
|
||||
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
|
||||
trilist.OnlineStatusChange += (d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
{
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
}
|
||||
};
|
||||
|
||||
LinkSingleTechSensorToApi(occController, trilist, joinMap);
|
||||
|
||||
LinkDualTechSensorToApi(occController, trilist, joinMap);
|
||||
}
|
||||
|
||||
private static void LinkDualTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
GlsOccupancySensorBaseJoinMap joinMap)
|
||||
{
|
||||
var odtOccController = occController as GlsOdtOccupancySensorController;
|
||||
|
||||
if (odtOccController == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// OR When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
|
||||
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
|
||||
|
||||
// AND When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
|
||||
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
|
||||
|
||||
// Ultrasonic A Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
|
||||
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
|
||||
|
||||
// Ultrasonic B Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
|
||||
odtOccController.UltrasonicBEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber,
|
||||
odtOccController.IncrementUsSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber,
|
||||
odtOccController.DecrementUsSensitivityInOccupiedState);
|
||||
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber,
|
||||
odtOccController.IncrementUsSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber,
|
||||
odtOccController.DecrementUsSensitivityInVacantState);
|
||||
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
|
||||
|
||||
//Sensor Raw States
|
||||
odtOccController.RawOccupancyPirFeedback.LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
|
||||
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
|
||||
}
|
||||
|
||||
private static void LinkSingleTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
GlsOccupancySensorBaseJoinMap joinMap)
|
||||
{
|
||||
// Occupied status
|
||||
trilist.SetBoolSigAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
|
||||
trilist.SetBoolSigAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
|
||||
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
|
||||
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(
|
||||
trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
|
||||
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
|
||||
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
|
||||
|
||||
// Timouts
|
||||
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
|
||||
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
|
||||
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
|
||||
|
||||
// LED Flash
|
||||
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
|
||||
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
|
||||
|
||||
// Short Timeout
|
||||
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
|
||||
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
|
||||
|
||||
// PIR Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
|
||||
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber,
|
||||
occController.IncrementPirSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber,
|
||||
occController.DecrementPirSensitivityInOccupiedState);
|
||||
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber,
|
||||
occController.IncrementPirSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber,
|
||||
occController.DecrementPirSensitivityInVacantState);
|
||||
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
|
||||
|
||||
return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines configuration properties for Crestron GLS series occupancy sensors
|
||||
/// </summary>
|
||||
public class GlsOccupancySensorPropertiesConfig
|
||||
{
|
||||
// Single Technology Sensors (PIR): GlsOccupancySensorBase
|
||||
[JsonProperty("enablePir")]
|
||||
public bool? EnablePir { get; set; }
|
||||
|
||||
[JsonProperty("enableLedFlash")]
|
||||
public bool? EnableLedFlash { get; set; }
|
||||
|
||||
[JsonProperty("shortTimeoutState")]
|
||||
public bool? ShortTimeoutState { get; set; }
|
||||
|
||||
[JsonProperty("enableRawStates")]
|
||||
public bool? EnableRawStates { get; set; }
|
||||
|
||||
[JsonProperty("remoteTimeout")]
|
||||
public ushort? RemoteTimeout { get; set; }
|
||||
|
||||
[JsonProperty("internalPhotoSensorMinChange")]
|
||||
public ushort? InternalPhotoSensorMinChange { get; set; }
|
||||
|
||||
[JsonProperty("externalPhotoSensorMinChange")]
|
||||
public ushort? ExternalPhotoSensorMinChange { get; set; }
|
||||
|
||||
// Dual Technology Sensors: GlsOdtCCn
|
||||
[JsonProperty("enableUsA")]
|
||||
public bool? EnableUsA { get; set; }
|
||||
|
||||
[JsonProperty("enableUsB")]
|
||||
public bool? EnableUsB { get; set; }
|
||||
|
||||
[JsonProperty("orWhenVacatedState")]
|
||||
public bool? OrWhenVacatedState { get; set; }
|
||||
|
||||
[JsonProperty("andWhenVacatedState")]
|
||||
public bool? AndWhenVacatedState { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,183 +1,266 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Description("Wrapper class for Dual Technology GLS Occupancy Sensors")]
|
||||
[Description("Wrapper class for Dual Technology GLS Occupancy Sensors")]
|
||||
[ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0,\"enableUsA\": true,\"enableUsB\": true,\"orWhenVacatedState\": true}")]
|
||||
public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController
|
||||
{
|
||||
public new GlsOdtCCn OccSensor { get; private set; }
|
||||
{
|
||||
private GlsOdtCCn _occSensor;
|
||||
|
||||
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
|
||||
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
|
||||
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
|
||||
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
|
||||
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
|
||||
|
||||
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
|
||||
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
|
||||
|
||||
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
|
||||
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
|
||||
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
|
||||
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
|
||||
|
||||
|
||||
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
|
||||
DeviceConfig config)
|
||||
: base(key, config.Name)
|
||||
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
|
||||
DeviceConfig config)
|
||||
: base(key, config.Name, config)
|
||||
{
|
||||
AddPreActivationAction(() =>
|
||||
{
|
||||
_occSensor = preActivationFunc(config);
|
||||
|
||||
RegisterCrestronGenericBase(_occSensor);
|
||||
|
||||
RegisterGlsOccupancySensorBaseController(_occSensor);
|
||||
|
||||
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);
|
||||
|
||||
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => _occSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected override void ApplySettingsToSensorFromConfig()
|
||||
{
|
||||
AddPreActivationAction(() =>
|
||||
base.ApplySettingsToSensorFromConfig();
|
||||
|
||||
if (PropertiesConfig.EnableUsA != null)
|
||||
{
|
||||
OccSensor = preActivationFunc(config);
|
||||
Debug.Console(1, this, "EnableUsA found, attempting to set value from config");
|
||||
SetUsAEnable((bool)PropertiesConfig.EnableUsA);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "EnableUsA null, no value specified in config");
|
||||
}
|
||||
|
||||
RegisterCrestronGenericBase(OccSensor);
|
||||
|
||||
RegisterGlsOdtSensorBaseController(OccSensor);
|
||||
if (PropertiesConfig.EnableUsB != null)
|
||||
{
|
||||
Debug.Console(1, this, "EnableUsB found, attempting to set value from config");
|
||||
SetUsBEnable((bool)PropertiesConfig.EnableUsB);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "EnablePir null, no value specified in config");
|
||||
}
|
||||
|
||||
AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue);
|
||||
|
||||
OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue);
|
||||
if (PropertiesConfig.OrWhenVacatedState != null)
|
||||
{
|
||||
SetOrWhenVacatedState((bool)PropertiesConfig.OrWhenVacatedState);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
|
||||
|
||||
});
|
||||
if (PropertiesConfig.AndWhenVacatedState != null)
|
||||
{
|
||||
SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId:
|
||||
AndWhenVacatedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId:
|
||||
OrWhenVacatedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.UsAEnabledFeedbackEventId:
|
||||
UltrasonicAEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.UsBEnabledFeedbackEventId:
|
||||
UltrasonicBEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId:
|
||||
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId:
|
||||
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
base.OccSensor_GlsOccupancySensorChange(device, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId:
|
||||
RawOccupancyPirFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId:
|
||||
RawOccupancyUsFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
base.OccSensor_BaseEvent(device, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the OrWhenVacated state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetOrWhenVacatedState(bool state)
|
||||
{
|
||||
_occSensor.OrWhenVacated.BoolValue = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the AndWhenVacated state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetAndWhenVacatedState(bool state)
|
||||
{
|
||||
_occSensor.AndWhenVacated.BoolValue = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the Ultrasonic A sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetUsAEnable(bool state)
|
||||
{
|
||||
_occSensor.EnableUsA.BoolValue = state;
|
||||
_occSensor.DisableUsA.BoolValue = !state;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the Ultrasonic B sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetUsBEnable(bool state)
|
||||
{
|
||||
_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;
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to print occ sensor settings to console.
|
||||
/// </summary>
|
||||
public override void GetSettings()
|
||||
{
|
||||
base.GetSettings();
|
||||
|
||||
Debug.Console(0, this, "Ultrasonic Enabled A: {0} | B: {1}",
|
||||
_occSensor.UsAEnabledFeedback.BoolValue,
|
||||
_occSensor.UsBEnabledFeedback.BoolValue);
|
||||
|
||||
Debug.Console(0, this, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}",
|
||||
_occSensor.UsSensitivityInOccupiedStateFeedback.UShortValue,
|
||||
_occSensor.UsSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
var dash = new string('*', 50);
|
||||
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory<GlsOdtOccupancySensorController>
|
||||
{
|
||||
public GlsOdtOccupancySensorControllerFactory()
|
||||
{
|
||||
if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId)
|
||||
AndWhenVacatedFeedback.FireUpdate();
|
||||
else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId)
|
||||
OrWhenVacatedFeedback.FireUpdate();
|
||||
else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId)
|
||||
UltrasonicAEnabledFeedback.FireUpdate();
|
||||
else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId)
|
||||
UltrasonicBEnabledFeedback.FireUpdate();
|
||||
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId)
|
||||
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
|
||||
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId)
|
||||
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
|
||||
|
||||
base.OccSensor_GlsOccupancySensorChange(device, args);
|
||||
TypeNames = new List<string> { "glsodtccn" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId)
|
||||
RawOccupancyPirFeedback.FireUpdate();
|
||||
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId)
|
||||
RawOccupancyUsFeedback.FireUpdate();
|
||||
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
|
||||
|
||||
base.OccSensor_BaseEvent(device, args);
|
||||
return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the OrWhenVacated state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetOrWhenVacatedState(bool state)
|
||||
{
|
||||
OccSensor.OrWhenVacated.BoolValue = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the AndWhenVacated state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetAndWhenVacatedState(bool state)
|
||||
{
|
||||
OccSensor.AndWhenVacated.BoolValue = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the Ultrasonic A sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetUsAEnable(bool state)
|
||||
{
|
||||
OccSensor.EnableUsA.BoolValue = state;
|
||||
OccSensor.DisableUsA.BoolValue = !state;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the Ultrasonic B sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetUsBEnable(bool state)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
#region PreActivation
|
||||
|
||||
private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc)
|
||||
{
|
||||
var control = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var cresnetId = control.CresnetIdInt;
|
||||
var branchId = control.ControlPortNumber;
|
||||
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
|
||||
var parentKey = String.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
|
||||
|
||||
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
@@ -194,24 +277,6 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory<GlsOdtOccupancySensorController>
|
||||
{
|
||||
public GlsOdtOccupancySensorControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "glsodtccn" };
|
||||
}
|
||||
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
|
||||
|
||||
return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class GlsOirOccupancySensorController:GlsOccupancySensorBaseController
|
||||
{
|
||||
private GlsOirCCn _occSensor;
|
||||
|
||||
public GlsOirOccupancySensorController(string key, Func<DeviceConfig, GlsOirCCn> preActivationFunc,DeviceConfig config) : this(key,config.Name, preActivationFunc, config)
|
||||
{
|
||||
}
|
||||
|
||||
public GlsOirOccupancySensorController(string key, string name, Func<DeviceConfig, GlsOirCCn> preActivationFunc, DeviceConfig config) : base(key, name, config)
|
||||
{
|
||||
AddPreActivationAction(() =>
|
||||
{
|
||||
_occSensor = preActivationFunc(config);
|
||||
|
||||
RegisterCrestronGenericBase(_occSensor);
|
||||
|
||||
RegisterGlsOccupancySensorBaseController(_occSensor);
|
||||
});
|
||||
}
|
||||
|
||||
#region Overrides of CrestronGenericBridgeableBaseDevice
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<GlsOccupancySensorBaseController>
|
||||
{
|
||||
public GlsOccupancySensorBaseControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "glsoirccn" };
|
||||
}
|
||||
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new GlsOirOccupancySensorController Device");
|
||||
|
||||
return new GlsOirOccupancySensorController(dc.Key, GetGlsOirCCn, dc);
|
||||
}
|
||||
|
||||
private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc)
|
||||
{
|
||||
var control = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var cresnetId = control.CresnetIdInt;
|
||||
var branchId = control.ControlPortNumber;
|
||||
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
|
||||
|
||||
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
|
||||
return new GlsOirCCn(cresnetId, Global.ControlSystem);
|
||||
}
|
||||
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
|
||||
|
||||
if (cresnetBridge != null)
|
||||
{
|
||||
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
|
||||
return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
|
||||
}
|
||||
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash_Essentials_Core.Bridges.JoinMaps;
|
||||
using PepperDash.Essentials.Core.Bridges.JoinMaps;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -143,6 +143,7 @@
|
||||
<Compile Include="Bridges\JoinMaps\Hrxxx0WirelessRemoteControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\IBasicCommunicationJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\IDigitalInputJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\IRBlurayBaseJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\SetTopBoxControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
|
||||
@@ -183,6 +184,9 @@
|
||||
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
|
||||
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
|
||||
<Compile Include="Crestron IO\StatusSign\StatusSignController.cs" />
|
||||
<Compile Include="Device Info\DeviceInfo.cs" />
|
||||
<Compile Include="Device Info\DeviceInfoEventArgs.cs" />
|
||||
<Compile Include="Device Info\IDeviceInfoProvider.cs" />
|
||||
<Compile Include="Devices\CodecInterfaces.cs" />
|
||||
<Compile Include="Devices\CrestronProcessor.cs" />
|
||||
<Compile Include="Devices\DeviceApiBase.cs" />
|
||||
@@ -196,6 +200,7 @@
|
||||
<Compile Include="Devices\PC\Laptop.cs" />
|
||||
<Compile Include="Devices\ReconfigurableDevice.cs" />
|
||||
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" />
|
||||
<Compile Include="DeviceTypeInterfaces\IHasBranding.cs" />
|
||||
@@ -216,10 +221,15 @@
|
||||
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
|
||||
<Compile Include="Fusion\FusionEventHandlers.cs" />
|
||||
<Compile Include="Fusion\FusionProcessorQueries.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs" />
|
||||
<Compile Include="Fusion\FusionRviDataClasses.cs" />
|
||||
<Compile Include="Gateways\CenRfgwController.cs" />
|
||||
<Compile Include="Gateways\EssentialsRfGatewayConfig.cs" />
|
||||
<Compile Include="Global\EthernetAdapterInfo.cs" />
|
||||
<Compile Include="Interfaces\ILogStrings.cs" />
|
||||
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
|
||||
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
|
||||
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
|
||||
<Compile Include="Queues\ComsMessage.cs" />
|
||||
<Compile Include="Queues\ProcessStringMessage.cs" />
|
||||
<Compile Include="Queues\GenericQueue.cs" />
|
||||
@@ -275,6 +285,7 @@
|
||||
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
|
||||
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
|
||||
<Compile Include="Room\EssentialsRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
|
||||
<Compile Include="Room\Interfaces.cs" />
|
||||
<Compile Include="Room\iOccupancyStatusProvider.cs" />
|
||||
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
|
||||
@@ -318,6 +329,7 @@
|
||||
<Compile Include="Routing\TieLine.cs" />
|
||||
<Compile Include="Queues\StringResponseProcessor.cs" />
|
||||
<Compile Include="Timers\CountdownTimer.cs" />
|
||||
<Compile Include="Timers\RetriggerableTimer.cs" />
|
||||
<Compile Include="Touchpanels\CrestronTouchpanelPropertiesConfig.cs" />
|
||||
<Compile Include="Touchpanels\Interfaces.cs" />
|
||||
<Compile Include="Touchpanels\Keyboards\HabaneroKeyboardController.cs" />
|
||||
@@ -328,6 +340,7 @@
|
||||
<Compile Include="UI PageManagers\SinglePageManager.cs" />
|
||||
<Compile Include="UI PageManagers\PageManager.cs" />
|
||||
<Compile Include="UI PageManagers\SetTopBoxTwoPanelPageManager.cs" />
|
||||
<Compile Include="Utilities\ActionSequence.cs" />
|
||||
<Compile Include="VideoStatus\VideoStatusOutputs.cs" />
|
||||
<Compile Include="Crestron\CrestronGenericBaseDevice.cs" />
|
||||
<Compile Include="DeviceControlsParentInterfaces\IPresentationSource.cs" />
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tags>crestron 3series 4series</tags>
|
||||
<repository type="git" url="https://github.com/PepperDash/Essentials"/>
|
||||
<dependencies>
|
||||
<dependency id="PepperDashCore" version="[1.0, 1.1)"/>
|
||||
<dependency id="PepperDashCore" version="[1.0.45, 1.1.0)"/>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
|
||||
@@ -402,13 +402,16 @@ namespace PepperDash.Essentials
|
||||
/// Loads a
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
/// <param name="loadedAssembly"></param>
|
||||
static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly)
|
||||
{
|
||||
var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"\r\n********************\r\n\tPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n********************",
|
||||
plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name);
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,178 +1,300 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
//using SSMono.IO;
|
||||
using PepperDash.Core.WebApi.Presets;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Presets
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that represents the model behind presets display
|
||||
/// </summary>
|
||||
public class DevicePresetsModel : Device
|
||||
{
|
||||
public event EventHandler PresetsLoaded;
|
||||
/// <summary>
|
||||
/// Class that represents the model behind presets display
|
||||
/// </summary>
|
||||
public class DevicePresetsModel : Device
|
||||
{
|
||||
public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel);
|
||||
|
||||
public int PulseTime { get; set; }
|
||||
public int DigitSpacingMS { get; set; }
|
||||
public bool PresetsAreLoaded { get; private set; }
|
||||
public delegate void PresetsSavedCallback(List<PresetChannel> presets);
|
||||
|
||||
public List<PresetChannel> PresetsList { get { return _PresetsList.ToList(); } }
|
||||
List<PresetChannel> _PresetsList;
|
||||
public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } }
|
||||
private readonly CCriticalSection _fileOps = new CCriticalSection();
|
||||
private readonly bool _initSuccess;
|
||||
|
||||
public bool UseLocalImageStorage { get; set; }
|
||||
public string ImagesLocalHostPrefix { get; set; }
|
||||
public string ImagesPathPrefix { get; set; }
|
||||
public string ListPathPrefix { get; set; }
|
||||
private readonly ISetTopBoxNumericKeypad _setTopBox;
|
||||
|
||||
/// <summary>
|
||||
/// The methods on the STB device to call when dialing
|
||||
/// </summary>
|
||||
Dictionary<char, Action<bool>> DialFunctions;
|
||||
Action<bool> EnterFunction;
|
||||
/// <summary>
|
||||
/// The methods on the STB device to call when dialing
|
||||
/// </summary>
|
||||
private Dictionary<char, Action<bool>> _dialFunctions;
|
||||
|
||||
bool DialIsRunning;
|
||||
string FilePath;
|
||||
bool InitSuccess;
|
||||
//SSMono.IO.FileSystemWatcher ListWatcher;
|
||||
private bool _dialIsRunning;
|
||||
private Action<bool> _enterFunction;
|
||||
private string _filePath;
|
||||
|
||||
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
|
||||
: base(key)
|
||||
{
|
||||
PulseTime = 150;
|
||||
DigitSpacingMS = 150;
|
||||
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
|
||||
: this(key, fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
_setTopBox = setTopBox;
|
||||
|
||||
try
|
||||
{
|
||||
// Grab the digit functions from the device
|
||||
// If any fail, the whole thing fails peacefully
|
||||
DialFunctions = new Dictionary<char, Action<bool>>(10)
|
||||
{
|
||||
{ '1', setTopBox.Digit1 },
|
||||
{ '2', setTopBox.Digit2 },
|
||||
{ '3', setTopBox.Digit3 },
|
||||
{ '4', setTopBox.Digit4 },
|
||||
{ '5', setTopBox.Digit5 },
|
||||
{ '6', setTopBox.Digit6 },
|
||||
{ '7', setTopBox.Digit7 },
|
||||
{ '8', setTopBox.Digit8 },
|
||||
{ '9', setTopBox.Digit9 },
|
||||
{ '0', setTopBox.Digit0 },
|
||||
{ '-', setTopBox.Dash }
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
|
||||
DialFunctions = null;
|
||||
return;
|
||||
}
|
||||
// Grab the digit functions from the device
|
||||
// If any fail, the whole thing fails peacefully
|
||||
_dialFunctions = new Dictionary<char, Action<bool>>(10)
|
||||
{
|
||||
{'1', setTopBox.Digit1},
|
||||
{'2', setTopBox.Digit2},
|
||||
{'3', setTopBox.Digit3},
|
||||
{'4', setTopBox.Digit4},
|
||||
{'5', setTopBox.Digit5},
|
||||
{'6', setTopBox.Digit6},
|
||||
{'7', setTopBox.Digit7},
|
||||
{'8', setTopBox.Digit8},
|
||||
{'9', setTopBox.Digit9},
|
||||
{'0', setTopBox.Digit0},
|
||||
{'-', setTopBox.Dash}
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
|
||||
_dialFunctions = null;
|
||||
return;
|
||||
}
|
||||
|
||||
EnterFunction = setTopBox.KeypadEnter;
|
||||
_enterFunction = setTopBox.KeypadEnter;
|
||||
}
|
||||
|
||||
UseLocalImageStorage = true;
|
||||
public DevicePresetsModel(string key, string fileName) : base(key)
|
||||
{
|
||||
PulseTime = 150;
|
||||
DigitSpacingMs = 150;
|
||||
|
||||
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0);
|
||||
ImagesPathPrefix = @"/presets/images.zip/";
|
||||
ListPathPrefix = @"/html/presets/lists/";
|
||||
UseLocalImageStorage = true;
|
||||
|
||||
SetFileName(fileName);
|
||||
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
|
||||
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
|
||||
ImagesPathPrefix = @"/presets/images.zip/";
|
||||
ListPathPrefix = @"/html/presets/lists/";
|
||||
|
||||
//ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists");
|
||||
//ListWatcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
//ListWatcher.EnableRaisingEvents = true;
|
||||
//ListWatcher.Changed += ListWatcher_Changed;
|
||||
InitSuccess = true;
|
||||
}
|
||||
SetFileName(fileName);
|
||||
|
||||
_initSuccess = true;
|
||||
}
|
||||
|
||||
public event PresetRecalledCallback PresetRecalled;
|
||||
public event PresetsSavedCallback PresetsSaved;
|
||||
|
||||
public int PulseTime { get; set; }
|
||||
public int DigitSpacingMs { get; set; }
|
||||
public bool PresetsAreLoaded { get; private set; }
|
||||
|
||||
public List<PresetChannel> PresetsList { get; private set; }
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return PresetsList != null ? PresetsList.Count : 0; }
|
||||
}
|
||||
|
||||
public bool UseLocalImageStorage { get; set; }
|
||||
public string ImagesLocalHostPrefix { get; set; }
|
||||
public string ImagesPathPrefix { get; set; }
|
||||
public string ListPathPrefix { get; set; }
|
||||
public event EventHandler PresetsLoaded;
|
||||
|
||||
|
||||
public void SetFileName(string path)
|
||||
{
|
||||
FilePath = ListPathPrefix + path;
|
||||
LoadChannels();
|
||||
}
|
||||
public void SetFileName(string path)
|
||||
{
|
||||
_filePath = ListPathPrefix + path;
|
||||
|
||||
public void LoadChannels()
|
||||
{
|
||||
PresetsAreLoaded = false;
|
||||
try
|
||||
{
|
||||
var pl = JsonConvert.DeserializeObject<PresetsList>(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII));
|
||||
Name = pl.Name;
|
||||
_PresetsList = pl.Channels;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message);
|
||||
// Just save a default empty list
|
||||
_PresetsList = new List<PresetChannel>();
|
||||
}
|
||||
PresetsAreLoaded = true;
|
||||
Debug.Console(2, this, "Setting presets file path to {0}", _filePath);
|
||||
LoadChannels();
|
||||
}
|
||||
|
||||
var handler = PresetsLoaded;
|
||||
if (handler != null)
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
public void LoadChannels()
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileOps.Enter();
|
||||
|
||||
public void Dial(int presetNum)
|
||||
{
|
||||
if (presetNum <= _PresetsList.Count)
|
||||
Dial(_PresetsList[presetNum - 1].Channel);
|
||||
}
|
||||
Debug.Console(2, this, "Loading presets from {0}", _filePath);
|
||||
PresetsAreLoaded = false;
|
||||
try
|
||||
{
|
||||
var pl = JsonConvert.DeserializeObject<PresetsList>(File.ReadToEnd(_filePath, Encoding.ASCII));
|
||||
Name = pl.Name;
|
||||
PresetsList = pl.Channels;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
|
||||
_filePath, e.Message);
|
||||
// Just save a default empty list
|
||||
PresetsList = new List<PresetChannel>();
|
||||
}
|
||||
PresetsAreLoaded = true;
|
||||
|
||||
public void Dial(string chanNum)
|
||||
{
|
||||
if (DialIsRunning || !InitSuccess) return;
|
||||
if (DialFunctions == null)
|
||||
{
|
||||
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
|
||||
return;
|
||||
}
|
||||
var handler = PresetsLoaded;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_fileOps.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
DialIsRunning = true;
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
{
|
||||
foreach (var c in chanNum.ToCharArray())
|
||||
{
|
||||
if (DialFunctions.ContainsKey(c))
|
||||
Pulse(DialFunctions[c]);
|
||||
CrestronEnvironment.Sleep(DigitSpacingMS);
|
||||
}
|
||||
public void Dial(int presetNum)
|
||||
{
|
||||
if (presetNum <= PresetsList.Count)
|
||||
{
|
||||
Dial(PresetsList[presetNum - 1].Channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (EnterFunction != null)
|
||||
Pulse(EnterFunction);
|
||||
DialIsRunning = false;
|
||||
});
|
||||
}
|
||||
public void Dial(string chanNum)
|
||||
{
|
||||
if (_dialIsRunning || !_initSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_dialFunctions == null)
|
||||
{
|
||||
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
|
||||
return;
|
||||
}
|
||||
|
||||
void Pulse(Action<bool> act)
|
||||
{
|
||||
act(true);
|
||||
CrestronEnvironment.Sleep(PulseTime);
|
||||
act(false);
|
||||
}
|
||||
_dialIsRunning = true;
|
||||
CrestronInvoke.BeginInvoke(o =>
|
||||
{
|
||||
foreach (var c in chanNum.ToCharArray())
|
||||
{
|
||||
if (_dialFunctions.ContainsKey(c))
|
||||
{
|
||||
Pulse(_dialFunctions[c]);
|
||||
}
|
||||
CrestronEnvironment.Sleep(DigitSpacingMs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for filesystem watcher. When directory changes, this is called
|
||||
/// </summary>
|
||||
//void ListWatcher_Changed(object sender, FileSystemEventArgs e)
|
||||
//{
|
||||
// Debug.Console(1, this, "folder modified: {0}", e.FullPath);
|
||||
// if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// Debug.Console(1, this, "File changed: {0}", e.ChangeType);
|
||||
// LoadChannels();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
if (_enterFunction != null)
|
||||
{
|
||||
Pulse(_enterFunction);
|
||||
}
|
||||
_dialIsRunning = false;
|
||||
});
|
||||
|
||||
if (_setTopBox == null) return;
|
||||
|
||||
OnPresetRecalled(_setTopBox, chanNum);
|
||||
}
|
||||
|
||||
public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox)
|
||||
{
|
||||
if (presetNum <= PresetsList.Count)
|
||||
{
|
||||
Dial(PresetsList[presetNum - 1].Channel, setTopBox);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
|
||||
{
|
||||
_dialFunctions = new Dictionary<char, Action<bool>>(10)
|
||||
{
|
||||
{'1', setTopBox.Digit1},
|
||||
{'2', setTopBox.Digit2},
|
||||
{'3', setTopBox.Digit3},
|
||||
{'4', setTopBox.Digit4},
|
||||
{'5', setTopBox.Digit5},
|
||||
{'6', setTopBox.Digit6},
|
||||
{'7', setTopBox.Digit7},
|
||||
{'8', setTopBox.Digit8},
|
||||
{'9', setTopBox.Digit9},
|
||||
{'0', setTopBox.Digit0},
|
||||
{'-', setTopBox.Dash}
|
||||
};
|
||||
|
||||
_enterFunction = setTopBox.KeypadEnter;
|
||||
|
||||
OnPresetRecalled(setTopBox, chanNum);
|
||||
|
||||
Dial(chanNum);
|
||||
}
|
||||
|
||||
private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel)
|
||||
{
|
||||
var handler = PresetRecalled;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(setTopBox, channel);
|
||||
}
|
||||
|
||||
public void UpdatePreset(int index, PresetChannel preset)
|
||||
{
|
||||
if (index >= PresetsList.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PresetsList[index] = preset;
|
||||
|
||||
SavePresets();
|
||||
|
||||
OnPresetsSaved();
|
||||
}
|
||||
|
||||
public void UpdatePresets(List<PresetChannel> presets)
|
||||
{
|
||||
PresetsList = presets;
|
||||
|
||||
SavePresets();
|
||||
|
||||
OnPresetsSaved();
|
||||
}
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
try
|
||||
{
|
||||
_fileOps.Enter();
|
||||
var pl = new PresetsList {Channels = PresetsList, Name = Name};
|
||||
var json = JsonConvert.SerializeObject(pl, Formatting.Indented);
|
||||
|
||||
using (var file = File.Open(_filePath, FileMode.Truncate))
|
||||
{
|
||||
file.Write(json, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_fileOps.Leave();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void OnPresetsSaved()
|
||||
{
|
||||
var handler = PresetsSaved;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(PresetsList);
|
||||
}
|
||||
|
||||
private void Pulse(Action<bool> act)
|
||||
{
|
||||
act(true);
|
||||
CrestronEnvironment.Sleep(PulseTime);
|
||||
act(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core.Presets
|
||||
public class PresetChannel
|
||||
{
|
||||
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
[JsonProperty(Required = Required.Always,PropertyName = "name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
|
||||
[JsonProperty(Required = Required.Always, PropertyName = "iconUrl")]
|
||||
public string IconUrl { get; set; }
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
|
||||
[JsonProperty(Required = Required.Always, PropertyName = "channel")]
|
||||
public string Channel { get; set; }
|
||||
}
|
||||
|
||||
public class PresetsList
|
||||
{
|
||||
[JsonProperty(Required=Required.Always)]
|
||||
[JsonProperty(Required=Required.Always,PropertyName = "name")]
|
||||
public string Name { get; set; }
|
||||
[JsonProperty(Required = Required.Always)]
|
||||
|
||||
[JsonProperty(Required = Required.Always, PropertyName = "channels")]
|
||||
public List<PresetChannel> Channels { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// IBasicCommunication Message for IQueue
|
||||
@@ -40,7 +40,79 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
|
||||
private void Validate(IBasicCommunication coms, object message)
|
||||
{
|
||||
if (_coms == null)
|
||||
if (coms == null)
|
||||
throw new ArgumentNullException("coms");
|
||||
|
||||
if (message == null)
|
||||
throw new ArgumentNullException("message");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispatchs the string/byte[] to the IBasicCommunication specified
|
||||
/// </summary>
|
||||
public void Dispatch()
|
||||
{
|
||||
if (_isByteMessage)
|
||||
{
|
||||
_coms.SendBytes(_bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
_coms.SendText(_string);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows either the byte[] or string to be sent
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return _bytes != null ? _bytes.ToString() : _string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// IBasicCommunication Message for IQueue
|
||||
/// </summary>
|
||||
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
|
||||
public class ComsMessage : IQueueMessage
|
||||
{
|
||||
private readonly byte[] _bytes;
|
||||
private readonly IBasicCommunication _coms;
|
||||
private readonly string _string;
|
||||
private readonly bool _isByteMessage;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a string message
|
||||
/// </summary>
|
||||
/// <param name="coms">IBasicCommunication to send the message</param>
|
||||
/// <param name="message">Message to send</param>
|
||||
public ComsMessage(IBasicCommunication coms, string message)
|
||||
{
|
||||
Validate(coms, message);
|
||||
_coms = coms;
|
||||
_string = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a byte message
|
||||
/// </summary>
|
||||
/// <param name="coms">IBasicCommunication to send the message</param>
|
||||
/// <param name="message">Message to send</param>
|
||||
public ComsMessage(IBasicCommunication coms, byte[] message)
|
||||
{
|
||||
Validate(coms, message);
|
||||
_coms = coms;
|
||||
_bytes = message;
|
||||
_isByteMessage = true;
|
||||
}
|
||||
|
||||
private void Validate(IBasicCommunication coms, object message)
|
||||
{
|
||||
if (coms == null)
|
||||
throw new ArgumentNullException("coms");
|
||||
|
||||
if (message == null)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// Threadsafe processing of queued items with pacing if required
|
||||
@@ -15,23 +15,140 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
protected readonly Thread _worker;
|
||||
protected readonly CEvent _waitHandle = new CEvent();
|
||||
|
||||
private readonly bool _delayEnabled;
|
||||
private readonly int _delayTime;
|
||||
private bool _delayEnabled;
|
||||
private int _delayTime;
|
||||
|
||||
private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority;
|
||||
|
||||
/// <summary>
|
||||
/// If the instance has been disposed.
|
||||
/// </summary>
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the capacity of the CrestronQueue (fixed Size property)
|
||||
/// </summary>
|
||||
public int QueueCapacity
|
||||
{
|
||||
get
|
||||
{
|
||||
return _queue.Size;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of elements currently in the CrestronQueue
|
||||
/// </summary>
|
||||
public int QueueCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _queue.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with no thread priority
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public GenericQueue(string key)
|
||||
: this(key, _defaultPriority, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with queue size
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="capacity">Fixed size for the queue to hold</param>
|
||||
public GenericQueue(string key, int capacity)
|
||||
: this(key, _defaultPriority, capacity, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for generic queue with no pacing
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
public GenericQueue(string key)
|
||||
/// <param name="pacing">Pacing in ms between actions</param>
|
||||
public GenericQueue(int pacing, string key)
|
||||
: this(key, _defaultPriority, 0, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing and capacity
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="pacing"></param>
|
||||
/// <param name="capacity"></param>
|
||||
public GenericQueue(string key, int pacing, int capacity)
|
||||
: this(key, _defaultPriority, capacity, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing and priority
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="pacing"></param>
|
||||
/// <param name="priority"></param>
|
||||
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
|
||||
: this(key, priority, 0, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing, priority and capacity
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="capacity"></param>
|
||||
public GenericQueue(string key, Thread.eThreadPriority priority, int capacity)
|
||||
: this(key, priority, capacity, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing, priority and capacity
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="pacing"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="capacity"></param>
|
||||
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
|
||||
: this(key, priority, capacity, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for generic queue with no pacing
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="capacity"></param>
|
||||
/// <param name="pacing"></param>
|
||||
protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing)
|
||||
{
|
||||
_key = key;
|
||||
_queue = new CrestronQueue<IQueueMessage>();
|
||||
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running);
|
||||
int cap = 25; // sets default
|
||||
if (capacity > 0)
|
||||
{
|
||||
cap = capacity; // overrides default
|
||||
}
|
||||
_queue = new CrestronQueue<IQueueMessage>(cap);
|
||||
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
|
||||
{
|
||||
Priority = priority
|
||||
};
|
||||
|
||||
SetDelayValues(pacing);
|
||||
}
|
||||
|
||||
private void SetDelayValues(int pacing)
|
||||
{
|
||||
_delayEnabled = pacing > 0;
|
||||
_delayTime = pacing;
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
|
||||
{
|
||||
@@ -41,17 +158,257 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
Dispose();
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread callback
|
||||
/// </summary>
|
||||
/// <param name="obj">The action used to process dequeued items</param>
|
||||
/// <returns>Null when the thread is exited</returns>
|
||||
private object ProcessQueue(object obj)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
IQueueMessage item = null;
|
||||
|
||||
if (_queue.Count > 0)
|
||||
{
|
||||
item = _queue.Dequeue();
|
||||
if (item == null)
|
||||
break;
|
||||
}
|
||||
if (item != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString());
|
||||
item.Dispatch();
|
||||
|
||||
if (_delayEnabled)
|
||||
Thread.Sleep(_delayTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
else _waitHandle.Wait();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Enqueue(IQueueMessage item)
|
||||
{
|
||||
if (Disposed)
|
||||
{
|
||||
Debug.Console(1, this, "I've been disposed so you can't enqueue any messages. Are you trying to dispatch a message while the program is stopping?");
|
||||
return;
|
||||
}
|
||||
|
||||
_queue.Enqueue(item);
|
||||
_waitHandle.Set();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the thread and cleans up resources. Thread cannot be restarted once
|
||||
/// disposed.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
CrestronEnvironment.GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Actually does the disposing. If you override this method, be sure to either call the base implementation
|
||||
/// or clean up all the resources yourself.
|
||||
/// </summary>
|
||||
/// <param name="disposing">set to true unless called from finalizer</param>
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (Disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Enqueue(null);
|
||||
_worker.Join();
|
||||
_waitHandle.Close();
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
|
||||
~GenericQueue()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Key
|
||||
/// </summary>
|
||||
public string Key
|
||||
{
|
||||
get { return _key; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// Threadsafe processing of queued items with pacing if required
|
||||
/// </summary>
|
||||
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
|
||||
public class GenericQueue : IQueue<IQueueMessage>
|
||||
{
|
||||
private readonly string _key;
|
||||
protected readonly CrestronQueue<IQueueMessage> _queue;
|
||||
protected readonly Thread _worker;
|
||||
protected readonly CEvent _waitHandle = new CEvent();
|
||||
|
||||
private bool _delayEnabled;
|
||||
private int _delayTime;
|
||||
|
||||
private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority;
|
||||
|
||||
/// <summary>
|
||||
/// If the instance has been disposed.
|
||||
/// </summary>
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the capacity of the CrestronQueue (fixed Size property)
|
||||
/// </summary>
|
||||
public int QueueCapacity
|
||||
{
|
||||
get
|
||||
{
|
||||
return _queue.Size;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of elements currently in the CrestronQueue
|
||||
/// </summary>
|
||||
public int QueueCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return _queue.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with no thread priority
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public GenericQueue(string key)
|
||||
: this(key, _defaultPriority, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with queue size
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="capacity">Fixed size for the queue to hold</param>
|
||||
public GenericQueue(string key, int capacity)
|
||||
: this(key, _defaultPriority, capacity, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for generic queue with no pacing
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
/// <param name="pacing">Pacing in ms between actions</param>
|
||||
public GenericQueue(string key, int pacing)
|
||||
: this(key)
|
||||
public GenericQueue(int pacing, string key)
|
||||
: this(key, _defaultPriority, 0, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing and capacity
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="pacing"></param>
|
||||
/// <param name="capacity"></param>
|
||||
public GenericQueue(string key, int pacing, int capacity)
|
||||
: this(key, _defaultPriority, capacity, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing and priority
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="pacing"></param>
|
||||
/// <param name="priority"></param>
|
||||
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
|
||||
: this(key, priority, 0, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing, priority and capacity
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="capacity"></param>
|
||||
public GenericQueue(string key, Thread.eThreadPriority priority, int capacity)
|
||||
: this(key, priority, capacity, 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with pacing, priority and capacity
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="pacing"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="capacity"></param>
|
||||
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
|
||||
: this(key, priority, capacity, pacing)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for generic queue with no pacing
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="capacity"></param>
|
||||
/// <param name="pacing"></param>
|
||||
protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing)
|
||||
{
|
||||
_key = key;
|
||||
int cap = 25; // sets default
|
||||
if (capacity > 0)
|
||||
{
|
||||
cap = capacity; // overrides default
|
||||
}
|
||||
_queue = new CrestronQueue<IQueueMessage>(cap);
|
||||
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
|
||||
{
|
||||
Priority = priority
|
||||
};
|
||||
|
||||
SetDelayValues(pacing);
|
||||
}
|
||||
|
||||
private void SetDelayValues(int pacing)
|
||||
{
|
||||
_delayEnabled = pacing > 0;
|
||||
_delayTime = pacing;
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
|
||||
{
|
||||
if (programEvent != eProgramStatusEventType.Stopping)
|
||||
return;
|
||||
|
||||
Dispose();
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,7 +440,7 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.ConsoleWithLog(0, this, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
else _waitHandle.Wait();
|
||||
|
||||
@@ -5,11 +5,21 @@ using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
public interface IQueue<T> : IKeyed, IDisposable where T : class
|
||||
{
|
||||
void Enqueue(T item);
|
||||
bool Disposed { get; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
|
||||
public interface IQueue<T> : IKeyed, IDisposable where T : class
|
||||
{
|
||||
void Enqueue(T item);
|
||||
bool Disposed { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,18 @@
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
public interface IQueueMessage
|
||||
{
|
||||
void Dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
|
||||
public interface IQueueMessage
|
||||
{
|
||||
void Dispatch();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// Message class for processing strings via an IQueue
|
||||
@@ -32,6 +32,50 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
_action(_message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To string
|
||||
/// </summary>
|
||||
/// <returns>The current message</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return _message ?? String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
/// <summary>
|
||||
/// Message class for processing strings via an IQueue
|
||||
/// </summary>
|
||||
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
|
||||
public class ProcessStringMessage : IQueueMessage
|
||||
{
|
||||
private readonly Action<string> _action;
|
||||
private readonly string _message;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="message">Message to be processed</param>
|
||||
/// <param name="action">Action to invoke on the message</param>
|
||||
public ProcessStringMessage(string message, Action<string> action)
|
||||
{
|
||||
_message = message;
|
||||
_action = action;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the string with the given action
|
||||
/// </summary>
|
||||
public void Dispatch()
|
||||
{
|
||||
if (_action == null || String.IsNullOrEmpty(_message))
|
||||
return;
|
||||
|
||||
_action(_message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To string
|
||||
/// </summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
namespace PepperDash.Essentials.Core.Queues
|
||||
{
|
||||
public sealed class StringResponseProcessor : IKeyed, IDisposable
|
||||
{
|
||||
@@ -98,6 +98,110 @@ namespace PepperDash_Essentials_Core.Queues
|
||||
/// </summary>
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
~StringResponseProcessor()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Queues
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
|
||||
public sealed class StringResponseProcessor : IKeyed, IDisposable
|
||||
{
|
||||
private readonly Action<string> _processStringAction;
|
||||
private readonly IQueue<IQueueMessage> _queue;
|
||||
private readonly IBasicCommunication _coms;
|
||||
private readonly CommunicationGather _gather;
|
||||
|
||||
private StringResponseProcessor(string key, Action<string> processStringAction)
|
||||
{
|
||||
_processStringAction = processStringAction;
|
||||
_queue = new GenericQueue(key);
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
|
||||
{
|
||||
if (programEvent != eProgramStatusEventType.Stopping)
|
||||
return;
|
||||
|
||||
Dispose();
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that builds an instance and subscribes to coms TextReceived for processing
|
||||
/// </summary>
|
||||
/// <param name="coms">Com port to process strings from</param>
|
||||
/// <param name="processStringAction">Action to process the incoming strings</param>
|
||||
public StringResponseProcessor(IBasicCommunication coms, Action<string> processStringAction)
|
||||
: this(coms.Key, processStringAction)
|
||||
{
|
||||
_coms = coms;
|
||||
coms.TextReceived += OnResponseReceived;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that builds an instance and subscribes to gather Line Received for processing
|
||||
/// </summary>
|
||||
/// <param name="gather">Gather to process strings from</param>
|
||||
/// <param name="processStringAction">Action to process the incoming strings</param>
|
||||
public StringResponseProcessor(CommunicationGather gather, Action<string> processStringAction)
|
||||
: this(gather.Port.Key, processStringAction)
|
||||
{
|
||||
_gather = gather;
|
||||
gather.LineReceived += OnResponseReceived;
|
||||
}
|
||||
|
||||
private void OnResponseReceived(object sender, GenericCommMethodReceiveTextArgs args)
|
||||
{
|
||||
_queue.Enqueue(new ProcessStringMessage(args.Text, _processStringAction));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Key
|
||||
/// </summary>
|
||||
public string Key
|
||||
{
|
||||
get { return _queue.Key; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the instance and cleans up resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
CrestronEnvironment.GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (Disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
if (_coms != null)
|
||||
_coms.TextReceived -= OnResponseReceived;
|
||||
|
||||
if (_gather != null)
|
||||
{
|
||||
_gather.LineReceived -= OnResponseReceived;
|
||||
_gather.Stop();
|
||||
}
|
||||
|
||||
_queue.Dispose();
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the instance has been disposed or not. If it has, you can not use it anymore
|
||||
/// </summary>
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
~StringResponseProcessor()
|
||||
{
|
||||
Dispose(false);
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
void _gateway_IsReadyEvent(object sender, PepperDash_Essentials_Core.IsReadyEventArgs e)
|
||||
void _gateway_IsReadyEvent(object sender, IsReadyEventArgs e)
|
||||
{
|
||||
if (e.IsReady != true) return;
|
||||
_remote = GetHr1x0WirelessRemote(_config);
|
||||
|
||||
@@ -169,10 +169,15 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "{0}:{1} @ {2}", SchEvent.Name, type, DateTime.Now);
|
||||
|
||||
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
|
||||
{
|
||||
SchEvent.Acknowledge();
|
||||
|
||||
if (SchEvent.Name == FeatureEnableEventName)
|
||||
{
|
||||
|
||||
if (PropertiesConfig.EnableRoomOnWhenOccupied)
|
||||
FeatureEnabled = true;
|
||||
|
||||
@@ -248,9 +253,8 @@ namespace PepperDash.Essentials.Core
|
||||
schEvent = new ScheduledEvent(name, FeatureEventGroup);
|
||||
|
||||
// Set up its initial properties
|
||||
|
||||
if(!schEvent.Acknowledgeable)
|
||||
schEvent.Acknowledgeable = true;
|
||||
|
||||
schEvent.Acknowledgeable = false;
|
||||
|
||||
if(!schEvent.Persistent)
|
||||
schEvent.Persistent = true;
|
||||
@@ -287,7 +291,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString());
|
||||
|
||||
CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
|
||||
//CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
|
||||
|
||||
schEvent.Recurrence.Weekly(eventRecurrennce);
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
public class EssentialsRoomScheduledEventsConfig
|
||||
{
|
||||
[JsonProperty("scheduledEvents")]
|
||||
public List<ScheduledEventConfig> ScheduledEvents;
|
||||
}
|
||||
|
||||
public class ScheduledEventConfig
|
||||
{
|
||||
[JsonProperty("key")]
|
||||
public string Key;
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name;
|
||||
|
||||
[JsonProperty("days")]
|
||||
public ScheduledEventCommon.eWeekDays Days;
|
||||
|
||||
[JsonProperty("time")]
|
||||
public string Time;
|
||||
|
||||
[JsonProperty("actions")]
|
||||
public List<DeviceActionWrapper> Actions;
|
||||
|
||||
[JsonProperty("persistent")]
|
||||
public bool Persistent;
|
||||
|
||||
[JsonProperty("acknowledgeable")]
|
||||
public bool Acknowledgeable;
|
||||
|
||||
[JsonProperty("enable")]
|
||||
public bool Enable;
|
||||
}
|
||||
}
|
||||
@@ -1,368 +1,388 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fires when the RoomOccupancy object is set
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||
|
||||
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
||||
|
||||
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
||||
|
||||
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
||||
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this room is Mobile Control Enabled
|
||||
/// </summary>
|
||||
public bool IsMobileControlEnabled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The bridge for this room if Mobile Control is enabled
|
||||
/// </summary>
|
||||
public IMobileControlRoomBridge MobileControlRoomBridge { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class EssentialsRoomBase : ReconfigurableDevice
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public BoolFeedback OnFeedback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fires when the RoomOccupancy object is set
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> RoomOccupancyIsSet;
|
||||
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; private set; }
|
||||
|
||||
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
|
||||
|
||||
public bool OccupancyStatusProviderIsRemote { get; private set; }
|
||||
|
||||
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
|
||||
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if this room is Mobile Control Enabled
|
||||
/// </summary>
|
||||
public bool IsMobileControlEnabled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The bridge for this room if Mobile Control is enabled
|
||||
/// </summary>
|
||||
public IMobileControlRoomBridge MobileControlRoomBridge { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
///
|
||||
protected string _SourceListKey;
|
||||
public virtual string SourceListKey {
|
||||
protected string _SourceListKey;
|
||||
public string SourceListKey {
|
||||
get
|
||||
{
|
||||
return _SourceListKey;
|
||||
}
|
||||
set
|
||||
private set
|
||||
{
|
||||
_SourceListKey = value;
|
||||
|
||||
if (value != _SourceListKey)
|
||||
{
|
||||
_SourceListKey = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for informing the UIs of a shutdown
|
||||
/// </summary>
|
||||
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
public eShutdownType ShutdownType { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase Emergency { get; set; }
|
||||
|
||||
public Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
||||
|
||||
public string LogoUrlLightBkgnd { get; set; }
|
||||
|
||||
public string LogoUrlDarkBkgnd { get; set; }
|
||||
|
||||
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
||||
|
||||
public eVacancyMode VacancyMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy prompt is displayed until shutdown
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy detected until prompt is displayed
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownPromptSeconds;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected abstract Func<bool> OnFeedbackFunc { get; }
|
||||
|
||||
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
|
||||
|
||||
/// <summary>
|
||||
/// When volume control devices change, should we zero the one that we are leaving?
|
||||
/// </summary>
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
||||
|
||||
|
||||
public EssentialsRoomBase(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
// Setup the ShutdownPromptTimer
|
||||
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
||||
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
||||
ShutdownType = eShutdownType.None;
|
||||
};
|
||||
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
||||
|
||||
ShutdownPromptSeconds = 60;
|
||||
ShutdownVacancySeconds = 120;
|
||||
|
||||
ShutdownType = eShutdownType.None;
|
||||
|
||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
//{
|
||||
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
||||
// ShutdownType = ShutdownType.Vacancy;
|
||||
//};
|
||||
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
|
||||
|
||||
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
||||
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
||||
VacancyMode = eVacancyMode.None;
|
||||
|
||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||
|
||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
if (RoomOccupancy != null)
|
||||
OnRoomOccupancyIsSet();
|
||||
});
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
SetUpMobileControl();
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If mobile control is enabled, sets the appropriate properties
|
||||
/// </summary>
|
||||
void SetUpMobileControl()
|
||||
{
|
||||
var mcBridgeKey = string.Format("mobileControlBridge-{0}", Key);
|
||||
var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey);
|
||||
if (mcBridge == null)
|
||||
{
|
||||
Debug.Console(1, this, "*********************Mobile Control Bridge Not found for this room.");
|
||||
IsMobileControlEnabled = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge;
|
||||
Debug.Console(1, this, "*********************Mobile Control Bridge found and enabled for this room");
|
||||
IsMobileControlEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
||||
{
|
||||
switch (VacancyMode)
|
||||
{
|
||||
case eVacancyMode.None:
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
break;
|
||||
case eVacancyMode.InInitialVacancy:
|
||||
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
||||
break;
|
||||
case eVacancyMode.InShutdownWarning:
|
||||
{
|
||||
StartShutdown(eShutdownType.Vacancy);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
public void StartShutdown(eShutdownType type)
|
||||
{
|
||||
// Check for shutdowns running. Manual should override other shutdowns
|
||||
|
||||
if (type == eShutdownType.Manual)
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
|
||||
else if (type == eShutdownType.Vacancy)
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
|
||||
ShutdownType = type;
|
||||
ShutdownPromptTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
public void StartRoomVacancyTimer(eVacancyMode mode)
|
||||
{
|
||||
if (mode == eVacancyMode.None)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
|
||||
else if (mode == eVacancyMode.InInitialVacancy)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
|
||||
else if (mode == eVacancyMode.InShutdownWarning)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = 60;
|
||||
VacancyMode = mode;
|
||||
RoomVacancyShutdownTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the vacancy mode and shutsdwon the room
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
VacancyMode = eVacancyMode.None;
|
||||
EndShutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is for the derived class to define it's specific shutdown
|
||||
/// requirements but should not be called directly. It is called by Shutdown()
|
||||
/// </summary>
|
||||
protected abstract void EndShutdown();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override this to implement a default volume level(s) method
|
||||
/// </summary>
|
||||
public abstract void SetDefaultLevels();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
|
||||
/// </summary>
|
||||
/// <param name="statusProvider"></param>
|
||||
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
|
||||
{
|
||||
if (statusProvider == null)
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", (statusProvider as Device).Key);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
||||
|
||||
// If status provider is fusion, set flag to remote
|
||||
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
||||
OccupancyStatusProviderIsRemote = true;
|
||||
|
||||
if(timeoutMinutes > 0)
|
||||
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
|
||||
|
||||
RoomOccupancy = statusProvider;
|
||||
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||
|
||||
OnRoomOccupancyIsSet();
|
||||
}
|
||||
|
||||
void OnRoomOccupancyIsSet()
|
||||
{
|
||||
var handler = RoomOccupancyIsSet;
|
||||
if (handler != null)
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to last source
|
||||
/// </summary>
|
||||
public abstract void PowerOnToDefaultOrLastSource();
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to default source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool RunDefaultPresentRoute();
|
||||
|
||||
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
|
||||
// Trigger the timer when the room is vacant
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Occupancy Detected");
|
||||
// Reset the timer when the room is occupied
|
||||
RoomVacancyShutdownTimer.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To describe the various ways a room may be shutting down
|
||||
/// </summary>
|
||||
public enum eShutdownType
|
||||
{
|
||||
None = 0,
|
||||
External,
|
||||
Manual,
|
||||
Vacancy
|
||||
}
|
||||
|
||||
public enum eVacancyMode
|
||||
{
|
||||
None = 0,
|
||||
InInitialVacancy,
|
||||
InShutdownWarning
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eWarmingCoolingMode
|
||||
{
|
||||
None,
|
||||
Warming,
|
||||
Cooling
|
||||
}
|
||||
|
||||
public abstract class EssentialsRoomEmergencyBase : IKeyed
|
||||
{
|
||||
public string Key { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected const string _defaultSourceListKey = "default";
|
||||
|
||||
/// <summary>
|
||||
/// Timer used for informing the UIs of a shutdown
|
||||
/// </summary>
|
||||
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
public eShutdownType ShutdownType { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase Emergency { get; set; }
|
||||
|
||||
public Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; }
|
||||
|
||||
public string LogoUrlLightBkgnd { get; set; }
|
||||
|
||||
public string LogoUrlDarkBkgnd { get; set; }
|
||||
|
||||
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
|
||||
|
||||
public eVacancyMode VacancyMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy prompt is displayed until shutdown
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownSeconds;
|
||||
|
||||
/// <summary>
|
||||
/// Seconds after vacancy detected until prompt is displayed
|
||||
/// </summary>
|
||||
protected int RoomVacancyShutdownPromptSeconds;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected abstract Func<bool> OnFeedbackFunc { get; }
|
||||
|
||||
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
|
||||
|
||||
/// <summary>
|
||||
/// When volume control devices change, should we zero the one that we are leaving?
|
||||
/// </summary>
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
|
||||
|
||||
|
||||
public EssentialsRoomBase(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
// Setup the ShutdownPromptTimer
|
||||
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
|
||||
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
|
||||
ShutdownType = eShutdownType.None;
|
||||
};
|
||||
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
|
||||
|
||||
ShutdownPromptSeconds = 60;
|
||||
ShutdownVacancySeconds = 120;
|
||||
|
||||
ShutdownType = eShutdownType.None;
|
||||
|
||||
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
|
||||
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
|
||||
//{
|
||||
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
|
||||
// ShutdownType = ShutdownType.Vacancy;
|
||||
//};
|
||||
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
|
||||
|
||||
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
|
||||
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
|
||||
VacancyMode = eVacancyMode.None;
|
||||
|
||||
OnFeedback = new BoolFeedback(OnFeedbackFunc);
|
||||
|
||||
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
if (RoomOccupancy != null)
|
||||
OnRoomOccupancyIsSet();
|
||||
});
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
SetUpMobileControl();
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the SourceListKey property to the passed in value or the default if no value passed in
|
||||
/// </summary>
|
||||
/// <param name="sourceListKey"></param>
|
||||
protected void SetSourceListKey(string sourceListKey)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
SourceListKey = sourceListKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceListKey = _defaultSourceListKey;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If mobile control is enabled, sets the appropriate properties
|
||||
/// </summary>
|
||||
void SetUpMobileControl()
|
||||
{
|
||||
var mcBridgeKey = string.Format("mobileControlBridge-{0}", Key);
|
||||
var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey);
|
||||
if (mcBridge == null)
|
||||
{
|
||||
Debug.Console(1, this, "*********************Mobile Control Bridge Not found for this room.");
|
||||
IsMobileControlEnabled = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge;
|
||||
Debug.Console(1, this, "*********************Mobile Control Bridge found and enabled for this room");
|
||||
IsMobileControlEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
|
||||
{
|
||||
switch (VacancyMode)
|
||||
{
|
||||
case eVacancyMode.None:
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
break;
|
||||
case eVacancyMode.InInitialVacancy:
|
||||
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
|
||||
break;
|
||||
case eVacancyMode.InShutdownWarning:
|
||||
{
|
||||
StartShutdown(eShutdownType.Vacancy);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
public void StartShutdown(eShutdownType type)
|
||||
{
|
||||
// Check for shutdowns running. Manual should override other shutdowns
|
||||
|
||||
if (type == eShutdownType.Manual)
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
|
||||
else if (type == eShutdownType.Vacancy)
|
||||
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
|
||||
ShutdownType = type;
|
||||
ShutdownPromptTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
public void StartRoomVacancyTimer(eVacancyMode mode)
|
||||
{
|
||||
if (mode == eVacancyMode.None)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
|
||||
else if (mode == eVacancyMode.InInitialVacancy)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
|
||||
else if (mode == eVacancyMode.InShutdownWarning)
|
||||
RoomVacancyShutdownTimer.SecondsToCount = 60;
|
||||
VacancyMode = mode;
|
||||
RoomVacancyShutdownTimer.Start();
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the vacancy mode and shutsdwon the room
|
||||
/// </summary>
|
||||
public void Shutdown()
|
||||
{
|
||||
VacancyMode = eVacancyMode.None;
|
||||
EndShutdown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is for the derived class to define it's specific shutdown
|
||||
/// requirements but should not be called directly. It is called by Shutdown()
|
||||
/// </summary>
|
||||
protected abstract void EndShutdown();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Override this to implement a default volume level(s) method
|
||||
/// </summary>
|
||||
public abstract void SetDefaultLevels();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
|
||||
/// </summary>
|
||||
/// <param name="statusProvider"></param>
|
||||
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
|
||||
{
|
||||
if (statusProvider == null)
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", (statusProvider as Device).Key);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
|
||||
|
||||
// If status provider is fusion, set flag to remote
|
||||
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
|
||||
OccupancyStatusProviderIsRemote = true;
|
||||
|
||||
if(timeoutMinutes > 0)
|
||||
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
|
||||
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
|
||||
|
||||
RoomOccupancy = statusProvider;
|
||||
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
|
||||
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||
|
||||
OnRoomOccupancyIsSet();
|
||||
}
|
||||
|
||||
void OnRoomOccupancyIsSet()
|
||||
{
|
||||
var handler = RoomOccupancyIsSet;
|
||||
if (handler != null)
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to last source
|
||||
/// </summary>
|
||||
public abstract void PowerOnToDefaultOrLastSource();
|
||||
|
||||
/// <summary>
|
||||
/// To allow base class to power room on to default source
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool RunDefaultPresentRoute();
|
||||
|
||||
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
|
||||
// Trigger the timer when the room is vacant
|
||||
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Occupancy Detected");
|
||||
// Reset the timer when the room is occupied
|
||||
RoomVacancyShutdownTimer.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
public abstract void RoomVacatedForTimeoutPeriod(object o);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To describe the various ways a room may be shutting down
|
||||
/// </summary>
|
||||
public enum eShutdownType
|
||||
{
|
||||
None = 0,
|
||||
External,
|
||||
Manual,
|
||||
Vacancy
|
||||
}
|
||||
|
||||
public enum eVacancyMode
|
||||
{
|
||||
None = 0,
|
||||
InInitialVacancy,
|
||||
InShutdownWarning
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum eWarmingCoolingMode
|
||||
{
|
||||
None,
|
||||
Warming,
|
||||
Cooling
|
||||
}
|
||||
|
||||
public abstract class EssentialsRoomEmergencyBase : IKeyed
|
||||
{
|
||||
public string Key { get; private set; }
|
||||
|
||||
public EssentialsRoomEmergencyBase(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,14 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simplified routing direct from source to destination
|
||||
/// </summary>
|
||||
public interface IRunDirectRouteAction
|
||||
{
|
||||
void RunDirectRoute(string sourceKey, string destinationKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For rooms that default presentation only routing
|
||||
/// </summary>
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
/// For fixed-source endpoint devices
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
[Obsolete("Please switch to IRoutingSink")]
|
||||
public interface IRoutingSinkNoSwitching : IRoutingSink
|
||||
{
|
||||
|
||||
@@ -92,6 +92,16 @@ namespace PepperDash.Essentials.Core
|
||||
void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType);
|
||||
}
|
||||
|
||||
public interface IRoutingWithClear : IRouting
|
||||
{
|
||||
/// <summary>
|
||||
/// Clears a route to an output, however a device needs to do that
|
||||
/// </summary>
|
||||
/// <param name="outputSelector">Output to clear</param>
|
||||
/// <param name="signalType">signal type to clear</param>
|
||||
void ClearRoute(object outputSelector, eRoutingSignalType signalType);
|
||||
}
|
||||
|
||||
public interface IRoutingNumeric : IRouting
|
||||
{
|
||||
void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type);
|
||||
@@ -111,10 +121,87 @@ namespace PepperDash.Essentials.Core
|
||||
IntFeedback AudioVideoSourceNumericFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRmcRouting with a feedback event
|
||||
/// </summary>
|
||||
public interface ITxRoutingWithFeedback : ITxRouting
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRmcRouting with a feedback event
|
||||
/// </summary>
|
||||
public interface IRmcRoutingWithFeedback : IRmcRouting
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRoutingOutputs devices as being a source - the start of the chain
|
||||
/// </summary>
|
||||
public interface IRoutingSource : IRoutingOutputs
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an event structure for reporting output route data
|
||||
/// </summary>
|
||||
public interface IRoutingFeedback : IKeyName
|
||||
{
|
||||
event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
//void OnSwitchChange(RoutingNumericEventArgs e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRoutingNumeric with a feedback event
|
||||
/// </summary>
|
||||
public interface IRoutingNumericWithFeedback : IRoutingNumeric, IRoutingFeedback
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRouting with a feedback event
|
||||
/// </summary>
|
||||
public interface IRoutingWithFeedback : IRouting, IRoutingFeedback
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class RoutingNumericEventArgs : EventArgs
|
||||
{
|
||||
|
||||
public uint? Output { get; set; }
|
||||
public uint? Input { get; set; }
|
||||
|
||||
public eRoutingSignalType SigType { get; set; }
|
||||
public RoutingInputPort InputPort { get; set; }
|
||||
public RoutingOutputPort OutputPort { get; set; }
|
||||
|
||||
public RoutingNumericEventArgs(uint output, uint input, eRoutingSignalType sigType) : this(output, input, null, null, sigType)
|
||||
{
|
||||
}
|
||||
|
||||
public RoutingNumericEventArgs(RoutingOutputPort outputPort, RoutingInputPort inputPort,
|
||||
eRoutingSignalType sigType)
|
||||
: this(null, null, outputPort, inputPort, sigType)
|
||||
{
|
||||
}
|
||||
|
||||
public RoutingNumericEventArgs()
|
||||
: this(null, null, null, null, 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public RoutingNumericEventArgs(uint? output, uint? input, RoutingOutputPort outputPort,
|
||||
RoutingInputPort inputPort, eRoutingSignalType sigType)
|
||||
{
|
||||
OutputPort = outputPort;
|
||||
InputPort = inputPort;
|
||||
|
||||
Output = output;
|
||||
Input = input;
|
||||
SigType = sigType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace PepperDash.Essentials.Core
|
||||
public string Key { get; private set; }
|
||||
|
||||
public BoolFeedback IsRunningFeedback { get; private set; }
|
||||
bool _IsRunning;
|
||||
bool _isRunning;
|
||||
|
||||
public IntFeedback PercentFeedback { get; private set; }
|
||||
public StringFeedback TimeRemainingFeedback { get; private set; }
|
||||
@@ -32,7 +32,7 @@ namespace PepperDash.Essentials.Core
|
||||
public DateTime StartTime { get; private set; }
|
||||
public DateTime FinishTime { get; private set; }
|
||||
|
||||
CTimer SecondTimer;
|
||||
private CTimer _secondTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
@@ -41,38 +41,34 @@ namespace PepperDash.Essentials.Core
|
||||
public SecondsCountdownTimer(string key)
|
||||
{
|
||||
Key = key;
|
||||
IsRunningFeedback = new BoolFeedback(() => _IsRunning);
|
||||
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)
|
||||
Debug.Console(2, this,
|
||||
"timeSpan.Minutes == {0}, timeSpan.Seconds == {1}, timeSpan.TotalSeconds == {2}",
|
||||
timeSpan.Minutes, timeSpan.Seconds, timeSpan.TotalSeconds);
|
||||
|
||||
if (Math.Floor(timeSpan.TotalSeconds) < 60 && Math.Floor(timeSpan.TotalSeconds) >= 0) //ignore milliseconds
|
||||
{
|
||||
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);
|
||||
return String.Format("{0:00}", timeSpan.Seconds);
|
||||
}
|
||||
|
||||
return Math.Floor(timeSpan.TotalSeconds) < 0
|
||||
? "00"
|
||||
: String.Format("{0:00}:{1:00}", 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;
|
||||
});
|
||||
PercentFeedback =
|
||||
new IntFeedback(
|
||||
() =>
|
||||
(int)
|
||||
(Math.Floor((FinishTime - DateTime.Now).TotalSeconds)/
|
||||
Math.Floor((FinishTime - StartTime).TotalSeconds)*100));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,15 +76,15 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
if (_IsRunning)
|
||||
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;
|
||||
if (_secondTimer != null)
|
||||
_secondTimer.Stop();
|
||||
_secondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000);
|
||||
_isRunning = true;
|
||||
IsRunningFeedback.FireUpdate();
|
||||
|
||||
var handler = HasStarted;
|
||||
@@ -101,7 +97,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
_IsRunning = false;
|
||||
_isRunning = false;
|
||||
Start();
|
||||
}
|
||||
|
||||
@@ -131,19 +127,22 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
void StopHelper()
|
||||
{
|
||||
if (SecondTimer != null)
|
||||
SecondTimer.Stop();
|
||||
_IsRunning = false;
|
||||
if (_secondTimer != null)
|
||||
_secondTimer.Stop();
|
||||
_isRunning = false;
|
||||
IsRunningFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
void SecondElapsedTimerCallback(object o)
|
||||
{
|
||||
if (DateTime.Now >= FinishTime)
|
||||
{
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
PercentFeedback.FireUpdate();
|
||||
TimeRemainingFeedback.FireUpdate();
|
||||
|
||||
if (DateTime.Now >= FinishTime)
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Timers
|
||||
{
|
||||
/// <summary>
|
||||
/// A device that runs a retriggerable timer and can execute actions specified in config
|
||||
/// </summary>
|
||||
[Description("A retriggerable timer device")]
|
||||
public class RetriggerableTimer : EssentialsDevice
|
||||
{
|
||||
private RetriggerableTimerPropertiesConfig _propertiesConfig;
|
||||
|
||||
private CTimer _timer;
|
||||
private long _timerIntervalMs;
|
||||
|
||||
public RetriggerableTimer(string key, DeviceConfig config)
|
||||
: base(key, config.Name)
|
||||
{
|
||||
var props = config.Properties.ToObject<RetriggerableTimerPropertiesConfig>();
|
||||
_propertiesConfig = props;
|
||||
|
||||
if (_propertiesConfig != null)
|
||||
{
|
||||
_timerIntervalMs = _propertiesConfig.TimerIntervalMs;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
if (_propertiesConfig.StartTimerOnActivation)
|
||||
{
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
private void CleanUpTimer()
|
||||
{
|
||||
if (_timer != null)
|
||||
{
|
||||
_timer.Stop();
|
||||
_timer.Dispose();
|
||||
}
|
||||
|
||||
_timer = null;
|
||||
}
|
||||
|
||||
public void StartTimer()
|
||||
{
|
||||
CleanUpTimer();
|
||||
Debug.Console(0, this, "Starting Timer");
|
||||
|
||||
_timer = new CTimer(TimerElapsedCallback, GetActionFromConfig(eRetriggerableTimerEvents.Elapsed), _timerIntervalMs, _timerIntervalMs);
|
||||
}
|
||||
|
||||
public void StopTimer()
|
||||
{
|
||||
Debug.Console(0, this, "Stopping Timer");
|
||||
_timer.Stop();
|
||||
|
||||
ExecuteAction(GetActionFromConfig(eRetriggerableTimerEvents.Stopped));
|
||||
}
|
||||
|
||||
private DeviceActionWrapper GetActionFromConfig(eRetriggerableTimerEvents eventType)
|
||||
{
|
||||
var action = _propertiesConfig.Events[eRetriggerableTimerEvents.Elapsed];
|
||||
|
||||
if (action != null)
|
||||
return action;
|
||||
else return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the Elapsed action from confing when the timer elapses
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
private void TimerElapsedCallback(object action)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Timer Elapsed. Executing Action");
|
||||
|
||||
if (action == null)
|
||||
{
|
||||
Debug.Console(1, this, "Timer elapsed but unable to execute action. Action is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
var devAction = action as DeviceActionWrapper;
|
||||
if (devAction != null)
|
||||
ExecuteAction(devAction);
|
||||
else
|
||||
{
|
||||
Debug.Console(2, this, "Unable to cast action as DeviceActionWrapper. Cannot Execute");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ExecuteAction(DeviceActionWrapper action)
|
||||
{
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
DeviceJsonApi.DoDeviceAction(action);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Error Executing Action: {0}", e);
|
||||
}
|
||||
//finally // Not sure this is needed
|
||||
//{
|
||||
// _Timer.Reset(0, _TimerIntervalMs);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration Properties for RetriggerableTimer
|
||||
/// </summary>
|
||||
public class RetriggerableTimerPropertiesConfig
|
||||
{
|
||||
[JsonProperty("startTimerOnActivation")]
|
||||
public bool StartTimerOnActivation { get; set; }
|
||||
|
||||
[JsonProperty("timerIntervalMs")]
|
||||
public long TimerIntervalMs { get; set; }
|
||||
|
||||
[JsonProperty("events")]
|
||||
public Dictionary<eRetriggerableTimerEvents, DeviceActionWrapper> Events { get; set; }
|
||||
|
||||
public RetriggerableTimerPropertiesConfig()
|
||||
{
|
||||
Events = new Dictionary<eRetriggerableTimerEvents, DeviceActionWrapper>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The set of values describing events on the timer
|
||||
/// </summary>
|
||||
public enum eRetriggerableTimerEvents
|
||||
{
|
||||
Elapsed,
|
||||
Stopped,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory class
|
||||
/// </summary>
|
||||
public class RetriggerableTimerFactory : EssentialsDeviceFactory<RetriggerableTimer>
|
||||
{
|
||||
public RetriggerableTimerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "retriggerabletimer" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new RetriggerableTimer Device");
|
||||
|
||||
return new RetriggerableTimer(dc.Key, dc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -169,9 +169,9 @@ namespace PepperDash.Essentials.Core.PageManagers
|
||||
}
|
||||
|
||||
// Build presets
|
||||
if (stb.HasPresets && stb.PresetsModel != null)
|
||||
if (stb.HasPresets && stb.TvPresets != null)
|
||||
{
|
||||
PresetsView = new DevicePresetsView(trilist, stb.PresetsModel);
|
||||
PresetsView = new DevicePresetsView(trilist, stb.TvPresets);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace PepperDash.Essentials.Core.PageManagers
|
||||
{
|
||||
SetTopBox = stb;
|
||||
TriList = trilist;
|
||||
if(stb.PresetsModel != null)
|
||||
PresetsView = new DevicePresetsView(trilist, stb.PresetsModel);
|
||||
if(stb.TvPresets != null)
|
||||
PresetsView = new DevicePresetsView(trilist, stb.TvPresets);
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.CrestronThread;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// A device that executes a sequence of actions with optional delays between actions
|
||||
/// </summary>
|
||||
[Description("A device that executes a sequence of actions with optional delays between actions")]
|
||||
public class ActionSequence : EssentialsDevice
|
||||
{
|
||||
private ActionSequencePropertiesConfig _propertiesConfig;
|
||||
|
||||
private CrestronQueue<SequencedDeviceActionWrapper> _actionQueue;
|
||||
|
||||
private Thread _worker;
|
||||
|
||||
private bool _allowActionsToExecute;
|
||||
|
||||
public ActionSequence(string key, DeviceConfig config)
|
||||
: base(key, config.Name)
|
||||
{
|
||||
var props = config.Properties.ToObject<ActionSequencePropertiesConfig>();
|
||||
_propertiesConfig = props;
|
||||
|
||||
if (_propertiesConfig != null)
|
||||
{
|
||||
if (_propertiesConfig.ActionSequence.Count > 0)
|
||||
{
|
||||
_actionQueue = new CrestronQueue<SequencedDeviceActionWrapper>(_propertiesConfig.ActionSequence.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts executing the sequenced actions
|
||||
/// </summary>
|
||||
public void StartSequence()
|
||||
{
|
||||
if (_worker !=null && _worker.ThreadState == Thread.eThreadStates.ThreadRunning)
|
||||
{
|
||||
Debug.Console(1, this, "Thread already running. Cannot Start Sequence");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Starting Action Sequence");
|
||||
_allowActionsToExecute = true;
|
||||
AddActionsToQueue();
|
||||
_worker = new Thread(ProcessActions, null, Thread.eThreadStartOptions.Running);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops executing the sequenced actions
|
||||
/// </summary>
|
||||
public void StopSequence()
|
||||
{
|
||||
Debug.Console(1, this, "Stopping Action Sequence");
|
||||
_allowActionsToExecute = false;
|
||||
_worker.Abort();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the queue from the configuration information
|
||||
/// </summary>
|
||||
private void AddActionsToQueue()
|
||||
{
|
||||
Debug.Console(1, this, "Adding {0} actions to queue", _propertiesConfig.ActionSequence.Count);
|
||||
|
||||
for (int i = 0; i < _propertiesConfig.ActionSequence.Count; i++)
|
||||
{
|
||||
_actionQueue.Enqueue(_propertiesConfig.ActionSequence[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private object ProcessActions(object obj)
|
||||
{
|
||||
while (_allowActionsToExecute && _actionQueue.Count > 0)
|
||||
{
|
||||
SequencedDeviceActionWrapper action = null;
|
||||
|
||||
action = _actionQueue.Dequeue();
|
||||
if (action == null)
|
||||
break;
|
||||
|
||||
// Delay before executing
|
||||
if (action.DelayMs > 0)
|
||||
Thread.Sleep(action.DelayMs);
|
||||
|
||||
ExecuteAction(action);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void ExecuteAction(DeviceActionWrapper action)
|
||||
{
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
DeviceJsonApi.DoDeviceAction(action);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Error Executing Action: {0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration Properties for ActionSequence
|
||||
/// </summary>
|
||||
public class ActionSequencePropertiesConfig
|
||||
{
|
||||
[JsonProperty("actionSequence")]
|
||||
public List<SequencedDeviceActionWrapper> ActionSequence { get; set; }
|
||||
|
||||
public ActionSequencePropertiesConfig()
|
||||
{
|
||||
ActionSequence = new List<SequencedDeviceActionWrapper>();
|
||||
}
|
||||
}
|
||||
|
||||
public class SequencedDeviceActionWrapper : DeviceActionWrapper
|
||||
{
|
||||
[JsonProperty("delayMs")]
|
||||
public int DelayMs { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory class
|
||||
/// </summary>
|
||||
public class ActionSequenceFactory : EssentialsDeviceFactory<ActionSequence>
|
||||
{
|
||||
public ActionSequenceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "actionsequence" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new ActionSequence Device");
|
||||
|
||||
return new ActionSequence(dc.Key, dc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ using PepperDash.Essentials.Core.Config;
|
||||
namespace PepperDash.Essentials.DM.AirMedia
|
||||
{
|
||||
[Description("Wrapper class for an AM-200 or AM-300")]
|
||||
public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingNumeric, IIROutputPorts, IComPorts
|
||||
public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IIROutputPorts, IComPorts
|
||||
{
|
||||
public AmX00 AirMedia { get; private set; }
|
||||
|
||||
@@ -29,6 +29,10 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
|
||||
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
public BoolFeedback IsInSessionFeedback { get; private set; }
|
||||
public IntFeedback ErrorFeedback { get; private set; }
|
||||
public IntFeedback NumberOfUsersConnectedFeedback { get; set; }
|
||||
@@ -43,6 +47,7 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props)
|
||||
: base(key, name, device)
|
||||
{
|
||||
|
||||
AirMedia = device;
|
||||
|
||||
DeviceConfig = dc;
|
||||
@@ -53,21 +58,36 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this));
|
||||
eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this)
|
||||
{
|
||||
FeedbackMatchObject = 0
|
||||
});
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this));
|
||||
eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this)
|
||||
{
|
||||
FeedbackMatchObject = 1
|
||||
});
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this));
|
||||
eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this)
|
||||
{
|
||||
FeedbackMatchObject = 2
|
||||
});
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this));
|
||||
eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this)
|
||||
{
|
||||
FeedbackMatchObject = 4
|
||||
});
|
||||
|
||||
if (AirMedia is Am300)
|
||||
{
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this));
|
||||
eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this)
|
||||
{
|
||||
FeedbackMatchObject = 3
|
||||
});
|
||||
}
|
||||
|
||||
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
|
||||
@@ -153,6 +173,17 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumberFeedback.JoinNumber]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
|
||||
void AirMedia_AirMediaChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
|
||||
{
|
||||
if (args.EventId == AirMediaInputSlot.AirMediaStatusFeedbackEventId)
|
||||
@@ -172,12 +203,20 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
void DisplayControl_DisplayControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
|
||||
{
|
||||
if (args.EventId == AmX00.VideoOutFeedbackEventId)
|
||||
{
|
||||
VideoOutFeedback.FireUpdate();
|
||||
|
||||
var localInputPort =
|
||||
InputPorts.FirstOrDefault(p => (int) p.FeedbackMatchObject == VideoOutFeedback.UShortValue);
|
||||
|
||||
OnSwitchChange(new RoutingNumericEventArgs(1, VideoOutFeedback.UShortValue, OutputPorts.First(),
|
||||
localInputPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
else if (args.EventId == AmX00.EnableAutomaticRoutingFeedbackEventId)
|
||||
AutomaticInputRoutingEnabledFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
void HdmiIn_StreamChange(Crestron.SimplSharpPro.DeviceSupport.Stream stream, Crestron.SimplSharpPro.DeviceSupport.StreamEventArgs args)
|
||||
void HdmiIn_StreamChange(Stream stream, Crestron.SimplSharpPro.DeviceSupport.StreamEventArgs args)
|
||||
{
|
||||
if (args.EventId == DMInputEventIds.SourceSyncEventId)
|
||||
HdmiVideoSyncDetectedFeedback.FireUpdate();
|
||||
|
||||
@@ -21,12 +21,17 @@ namespace PepperDash.Essentials.DM {
|
||||
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
|
||||
///
|
||||
/// </summary>
|
||||
public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumeric
|
||||
public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback
|
||||
{
|
||||
private const string NonePortKey = "inputCard0--None";
|
||||
|
||||
public DMChassisPropertiesConfig PropertiesConfig { get; set; }
|
||||
|
||||
public Switch Chassis { get; private set; }
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
// Feedbacks for EssentialDM
|
||||
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
|
||||
public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; }
|
||||
@@ -109,6 +114,10 @@ namespace PepperDash.Essentials.DM {
|
||||
controller.AddVolumeControl(outNum, audio);
|
||||
}
|
||||
|
||||
controller.InputPorts.Add(new RoutingInputPort(NonePortKey, eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.None, null, controller));
|
||||
|
||||
|
||||
controller.InputNames = properties.InputNames;
|
||||
controller.OutputNames = properties.OutputNames;
|
||||
controller.PropertiesConfig = properties;
|
||||
@@ -287,6 +296,15 @@ namespace PepperDash.Essentials.DM {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
|
||||
void AddHdmiInBladePorts(uint number, ICec cecPort) {
|
||||
@@ -355,49 +373,47 @@ namespace PepperDash.Essentials.DM {
|
||||
}
|
||||
|
||||
void AddHdmiOutBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, number);
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("hdmiOut{0}", number) , eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, number);
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutMmFiberBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, number);
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
void AddDmOutSmFiberBladePorts(uint number) {
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, number);
|
||||
AddOutputPortWithDebug(String.Format("outputBlade{0}", (number / 8 > 0 ? 1 : number / 8)), String.Format("dmOut{0}", number), eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, Chassis.Outputs[number]);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Adds InputPort
|
||||
/// </summary>
|
||||
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);
|
||||
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType)
|
||||
{
|
||||
AddInputPortWithDebug(cardNum, portName, sigType, portType, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds InputPort and sets Port as ICec object
|
||||
/// </summary>
|
||||
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) {
|
||||
private 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);
|
||||
var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this)
|
||||
{
|
||||
FeedbackMatchObject = Chassis.Inputs[cardNum]
|
||||
};
|
||||
|
||||
if (inputPort != null) {
|
||||
if (cecPort != null)
|
||||
inputPort.Port = cecPort;
|
||||
if (cecPort != null)
|
||||
inputPort.Port = cecPort;
|
||||
|
||||
InputPorts.Add(inputPort);
|
||||
}
|
||||
else
|
||||
Debug.Console(2, this, "inputPort is null");
|
||||
InputPorts.Add(inputPort);
|
||||
}
|
||||
|
||||
|
||||
@@ -407,7 +423,10 @@ namespace PepperDash.Essentials.DM {
|
||||
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));
|
||||
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||
{
|
||||
FeedbackMatchObject = Chassis.Outputs[(uint)selector]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -458,54 +477,84 @@ namespace PepperDash.Essentials.DM {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// </summary>
|
||||
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
private 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;
|
||||
switch (args.EventId)
|
||||
{
|
||||
case DMOutputEventIds.VolumeEventId:
|
||||
{
|
||||
if (VolumeControls.ContainsKey(output))
|
||||
{
|
||||
VolumeControls[args.Number].VolumeEventFromChassis();
|
||||
}
|
||||
case DMOutputEventIds.EndpointOnlineEventId: {
|
||||
Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
if(Chassis.Outputs[output].Endpoint != null)
|
||||
Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}", args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.EndpointOnlineEventId:
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
|
||||
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
|
||||
if (Chassis.Outputs[output].Endpoint != null)
|
||||
Debug.Console(2, this,
|
||||
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
|
||||
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
|
||||
|
||||
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();
|
||||
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:
|
||||
{
|
||||
|
||||
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
|
||||
|
||||
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
|
||||
inputNumber, output);
|
||||
|
||||
if (VideoOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
|
||||
|
||||
|
||||
VideoOutputFeedbacks[output].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs(output,
|
||||
inputNumber,
|
||||
localOutputPort,
|
||||
localInputPort,
|
||||
eRoutingSignalType.AudioVideo));
|
||||
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) {
|
||||
OutputVideoRouteNameFeedbacks[output].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.OutputNameEventId: {
|
||||
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
|
||||
OutputNameFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId);
|
||||
break;
|
||||
if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[output].FireUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DMOutputEventIds.OutputNameEventId:
|
||||
{
|
||||
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
|
||||
OutputNameFeedbacks[output].FireUpdate();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
|
||||
args.Number, args.EventId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -518,9 +567,7 @@ namespace PepperDash.Essentials.DM {
|
||||
void StartOffTimer(PortNumberType pnt) {
|
||||
if (RouteOffTimers.ContainsKey(pnt))
|
||||
return;
|
||||
RouteOffTimers[pnt] = new CTimer(o => {
|
||||
ExecuteSwitch(0, pnt.Number, pnt.Type);
|
||||
}, RouteOffTime);
|
||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -543,11 +590,22 @@ namespace PepperDash.Essentials.DM {
|
||||
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);
|
||||
var input = inputSelector as DMInput; // Cast can sometimes fail
|
||||
var output = outputSelector as DMOutput;
|
||||
|
||||
|
||||
if (output == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Warning,
|
||||
"Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector,
|
||||
outputSelector);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
if (input == null) {
|
||||
StartOffTimer(key);
|
||||
}
|
||||
else {
|
||||
@@ -560,13 +618,13 @@ namespace PepperDash.Essentials.DM {
|
||||
|
||||
|
||||
|
||||
var inCard = input == 0 ? null : Chassis.Inputs[input];
|
||||
var outCard = input == 0 ? null : Chassis.Outputs[output];
|
||||
/*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) return;
|
||||
if ((sigType & eRoutingSignalType.Video) != eRoutingSignalType.Video) return;
|
||||
Chassis.VideoEnter.BoolValue = true;
|
||||
Chassis.Outputs[output].VideoOut = inCard;
|
||||
output.VideoOut = input;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -575,7 +633,10 @@ namespace PepperDash.Essentials.DM {
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, sigType);
|
||||
var input = inputSelector == 0 ? null : Chassis.Inputs[inputSelector];
|
||||
var output = Chassis.Outputs[outputSelector];
|
||||
|
||||
ExecuteSwitch(input, output, sigType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,12 +18,17 @@ using PepperDash.Essentials.DM.Config;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
public class DmpsRoutingController : EssentialsBridgeableDevice, IRoutingNumeric, IHasFeedback
|
||||
{
|
||||
public class DmpsRoutingController : EssentialsBridgeableDevice, IRoutingNumericWithFeedback, IHasFeedback
|
||||
{
|
||||
private const string NonePortKey = "none";
|
||||
|
||||
public CrestronControlSystem Dmps { get; set; }
|
||||
public ISystemControl SystemControl { get; private set; }
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
// Feedbacks for EssentialDM
|
||||
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
|
||||
public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; }
|
||||
@@ -56,24 +61,34 @@ namespace PepperDash.Essentials.DM
|
||||
/// </summary>
|
||||
public string NoRouteText = "";
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
|
||||
public static DmpsRoutingController GetDmpsRoutingController(string key, string name,
|
||||
DmpsRoutingPropertiesConfig properties)
|
||||
{
|
||||
try
|
||||
{
|
||||
ISystemControl systemControl = null;
|
||||
|
||||
systemControl = Global.ControlSystem.SystemControl as ISystemControl;
|
||||
var systemControl = Global.ControlSystem.SystemControl;
|
||||
|
||||
if (systemControl == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var controller = new DmpsRoutingController(key, name, systemControl);
|
||||
|
||||
controller.InputNames = properties.InputNames;
|
||||
controller.OutputNames = properties.OutputNames;
|
||||
var controller = new DmpsRoutingController(key, name, systemControl)
|
||||
{
|
||||
InputNames = properties.InputNames,
|
||||
OutputNames = properties.OutputNames
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(properties.NoRouteText))
|
||||
controller.NoRouteText = properties.NoRouteText;
|
||||
@@ -81,9 +96,9 @@ namespace PepperDash.Essentials.DM
|
||||
return controller;
|
||||
|
||||
}
|
||||
catch (System.Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Error getting DMPS Controller:\r{0}", e);
|
||||
Debug.Console(0, "Error getting DMPS Controller:\r\n{0}", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -98,6 +113,7 @@ namespace PepperDash.Essentials.DM
|
||||
public DmpsRoutingController(string key, string name, ISystemControl systemControl)
|
||||
: base(key, name)
|
||||
{
|
||||
|
||||
Dmps = Global.ControlSystem;
|
||||
SystemControl = systemControl;
|
||||
|
||||
@@ -118,8 +134,8 @@ namespace PepperDash.Essentials.DM
|
||||
OutputEndpointOnlineFeedbacks = new Dictionary<uint, BoolFeedback>();
|
||||
|
||||
Debug.Console(1, this, "{0} Switcher Inputs Present.", Dmps.SwitcherInputs.Count);
|
||||
Debug.Console(1, this, "{0} Switcher Outputs Present.", Dmps.SwitcherOutputs.Count);
|
||||
|
||||
Debug.Console(1, this, "{0} Switcher Outputs Present.", Dmps.SwitcherOutputs.Count);
|
||||
|
||||
Debug.Console(1, this, "{0} Inputs in ControlSystem", Dmps.NumberOfSwitcherInputs);
|
||||
Debug.Console(1, this, "{0} Outputs in ControlSystem", Dmps.NumberOfSwitcherOutputs);
|
||||
|
||||
@@ -140,57 +156,57 @@ namespace PepperDash.Essentials.DM
|
||||
Dmps.DMOutputChange += Dmps_DMOutputChange;
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
private void SetOutputNames()
|
||||
{
|
||||
if (OutputNames == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var kvp in OutputNames)
|
||||
{
|
||||
var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput);
|
||||
if (output != null && output.Name.Type != eSigType.NA)
|
||||
{
|
||||
output.Name.StringValue = kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetInputNames()
|
||||
{
|
||||
if (InputNames == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var kvp in InputNames)
|
||||
{
|
||||
var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput);
|
||||
if (input != null && input.Name.Type != eSigType.NA)
|
||||
{
|
||||
input.Name.StringValue = kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void SetOutputNames()
|
||||
{
|
||||
if (OutputNames == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var kvp in OutputNames)
|
||||
{
|
||||
var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput);
|
||||
if (output != null && output.Name.Type != eSigType.NA)
|
||||
{
|
||||
output.Name.StringValue = kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetInputNames()
|
||||
{
|
||||
if (InputNames == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var kvp in InputNames)
|
||||
{
|
||||
var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput);
|
||||
if (input != null && input.Name.Type != eSigType.NA)
|
||||
{
|
||||
input.Name.StringValue = kvp.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
{
|
||||
var joinMap = new DmpsRoutingControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmpsRoutingControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
joinMap = JsonConvert.DeserializeObject<DmpsRoutingControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
@@ -199,194 +215,203 @@ namespace PepperDash.Essentials.DM
|
||||
LinkInputsToApi(trilist, joinMap);
|
||||
|
||||
LinkOutputsToApi(trilist, joinMap);
|
||||
}
|
||||
|
||||
private void LinkOutputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
|
||||
{
|
||||
for (uint i = 1; i <= Dmps.SwitcherOutputs.Count; i++)
|
||||
{
|
||||
Debug.Console(2, this, "Linking Output Card {0}", i);
|
||||
|
||||
var ioSlot = i;
|
||||
var ioSlotJoin = ioSlot - 1;
|
||||
|
||||
// Control
|
||||
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin,
|
||||
o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video));
|
||||
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin,
|
||||
o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio));
|
||||
|
||||
trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s =>
|
||||
{
|
||||
var outputCard = Dmps.SwitcherOutputs[ioSlot] as DMOutput;
|
||||
|
||||
//Debug.Console(2, dmpsRouter, "Output Name String Sig Action for Output Card {0}", ioSlot);
|
||||
|
||||
if (outputCard == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, dmpsRouter, "Card Type: {0}", outputCard.CardInputOutputType);
|
||||
|
||||
if (outputCard is Card.Dmps3CodecOutput || outputCard.NameFeedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, dmpsRouter, "NameFeedabck: {0}", outputCard.NameFeedback.StringValue);
|
||||
|
||||
if (outputCard.NameFeedback.StringValue != s && outputCard.Name != null)
|
||||
{
|
||||
outputCard.Name.StringValue = s;
|
||||
}
|
||||
});
|
||||
|
||||
// Feedback
|
||||
if (VideoOutputFeedbacks[ioSlot] != null)
|
||||
{
|
||||
VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (AudioOutputFeedbacks[ioSlot] != null)
|
||||
{
|
||||
AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputAudioRouteNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
|
||||
{
|
||||
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
|
||||
{
|
||||
Debug.Console(2, this, "Linking Input Card {0}", i);
|
||||
|
||||
var ioSlot = i;
|
||||
var ioSlotJoin = ioSlot - 1;
|
||||
|
||||
if (VideoInputSyncFeedbacks[ioSlot] != null)
|
||||
{
|
||||
VideoInputSyncFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
|
||||
if (InputNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
|
||||
trilist.SetStringSigAction(joinMap.InputNames.JoinNumber + ioSlotJoin, s =>
|
||||
{
|
||||
var inputCard = Dmps.SwitcherInputs[ioSlot] as DMInput;
|
||||
|
||||
if (inputCard == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputCard.NameFeedback == null || string.IsNullOrEmpty(inputCard.NameFeedback.StringValue) ||
|
||||
inputCard.NameFeedback.StringValue == s)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputCard.Name != null)
|
||||
{
|
||||
inputCard.Name.StringValue = s;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (InputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||
{
|
||||
InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void LinkOutputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
|
||||
{
|
||||
for (uint i = 1; i <= Dmps.SwitcherOutputs.Count; i++)
|
||||
{
|
||||
Debug.Console(2, this, "Linking Output Card {0}", i);
|
||||
|
||||
var ioSlot = i;
|
||||
var ioSlotJoin = ioSlot - 1;
|
||||
|
||||
// Control
|
||||
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin,
|
||||
o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video));
|
||||
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin,
|
||||
o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio));
|
||||
|
||||
trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s =>
|
||||
{
|
||||
var outputCard = Dmps.SwitcherOutputs[ioSlot] as DMOutput;
|
||||
|
||||
//Debug.Console(2, dmpsRouter, "Output Name String Sig Action for Output Card {0}", ioSlot);
|
||||
|
||||
if (outputCard == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, dmpsRouter, "Card Type: {0}", outputCard.CardInputOutputType);
|
||||
|
||||
if (outputCard is Card.Dmps3CodecOutput || outputCard.NameFeedback == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, dmpsRouter, "NameFeedabck: {0}", outputCard.NameFeedback.StringValue);
|
||||
|
||||
if (outputCard.NameFeedback.StringValue != s && outputCard.Name != null)
|
||||
{
|
||||
outputCard.Name.StringValue = s;
|
||||
}
|
||||
});
|
||||
|
||||
// Feedback
|
||||
if (VideoOutputFeedbacks[ioSlot] != null)
|
||||
{
|
||||
VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (AudioOutputFeedbacks[ioSlot] != null)
|
||||
{
|
||||
AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputVideoRouteNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputAudioRouteNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
if (OutputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||
{
|
||||
OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
|
||||
{
|
||||
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
|
||||
{
|
||||
Debug.Console(2, this, "Linking Input Card {0}", i);
|
||||
|
||||
var ioSlot = i;
|
||||
var ioSlotJoin = ioSlot - 1;
|
||||
|
||||
if (VideoInputSyncFeedbacks[ioSlot] != null)
|
||||
{
|
||||
VideoInputSyncFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
|
||||
if (InputNameFeedbacks[ioSlot] != null)
|
||||
{
|
||||
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
|
||||
trilist.SetStringSigAction(joinMap.InputNames.JoinNumber + ioSlotJoin, s =>
|
||||
{
|
||||
var inputCard = Dmps.SwitcherInputs[ioSlot] as DMInput;
|
||||
|
||||
if (inputCard == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputCard.NameFeedback == null || string.IsNullOrEmpty(inputCard.NameFeedback.StringValue) ||
|
||||
inputCard.NameFeedback.StringValue == s)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputCard.Name != null)
|
||||
{
|
||||
inputCard.Name.StringValue = s;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (InputEndpointOnlineFeedbacks[ioSlot] != null)
|
||||
{
|
||||
InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Iterate the SwitcherOutputs collection to setup feedbacks and add routing ports
|
||||
/// </summary>
|
||||
void SetupOutputCards()
|
||||
{
|
||||
foreach (var card in Dmps.SwitcherOutputs)
|
||||
{
|
||||
foreach (var card in Dmps.SwitcherOutputs)
|
||||
{
|
||||
Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType);
|
||||
|
||||
var outputCard = card as DMOutput;
|
||||
|
||||
if (outputCard == null)
|
||||
{
|
||||
Debug.Console(1, this, "Output card {0} is not a DMOutput", card.CardInputOutputType);
|
||||
continue;
|
||||
}
|
||||
|
||||
var outputCard = card as DMOutput;
|
||||
|
||||
if (outputCard == null)
|
||||
{
|
||||
Debug.Console(1, this, "Output card {0} is not a DMOutput", card.CardInputOutputType);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Adding Output Card Number {0} Type: {1}", outputCard.Number, outputCard.CardInputOutputType.ToString());
|
||||
VideoOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
|
||||
{
|
||||
if (outputCard.VideoOutFeedback != null) { return (ushort)outputCard.VideoOutFeedback.Number; }
|
||||
return 0;
|
||||
if (outputCard.VideoOutFeedback != null) { return (ushort)outputCard.VideoOutFeedback.Number; }
|
||||
return 0;
|
||||
;
|
||||
});
|
||||
AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
|
||||
{
|
||||
if (outputCard.AudioOutFeedback != null) { return (ushort)outputCard.AudioOutFeedback.Number; }
|
||||
return 0;
|
||||
;
|
||||
try
|
||||
{
|
||||
if (outputCard.AudioOutFeedback != null)
|
||||
{
|
||||
return (ushort) outputCard.AudioOutFeedback.Number;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
return (ushort) outputCard.AudioOutSourceFeedback;
|
||||
}
|
||||
});
|
||||
|
||||
OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
|
||||
{
|
||||
OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
|
||||
{
|
||||
if (outputCard.NameFeedback != null && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
|
||||
{
|
||||
Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue);
|
||||
return outputCard.NameFeedback.StringValue;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
OutputVideoRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
|
||||
{
|
||||
OutputVideoRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
|
||||
{
|
||||
if (outputCard.VideoOutFeedback != null && outputCard.VideoOutFeedback.NameFeedback != null)
|
||||
{
|
||||
return outputCard.VideoOutFeedback.NameFeedback.StringValue;
|
||||
}
|
||||
return NoRouteText;
|
||||
}
|
||||
return NoRouteText;
|
||||
});
|
||||
OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
|
||||
{
|
||||
OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
|
||||
{
|
||||
if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null)
|
||||
{
|
||||
return outputCard.AudioOutFeedback.NameFeedback.StringValue;
|
||||
}
|
||||
return NoRouteText;
|
||||
}
|
||||
return NoRouteText;
|
||||
});
|
||||
|
||||
OutputEndpointOnlineFeedbacks[outputCard.Number] = new BoolFeedback(() => outputCard.EndpointOnlineFeedback);
|
||||
|
||||
AddOutputCard(outputCard.Number, outputCard);
|
||||
AddOutputCard(outputCard.Number, outputCard);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,14 +428,11 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
Debug.Console(1, this, "Adding Input Card Number {0} Type: {1}", inputCard.Number, inputCard.CardInputOutputType.ToString());
|
||||
|
||||
InputEndpointOnlineFeedbacks[inputCard.Number] = new BoolFeedback(() => { return inputCard.EndpointOnlineFeedback; });
|
||||
InputEndpointOnlineFeedbacks[inputCard.Number] = new BoolFeedback(() => inputCard.EndpointOnlineFeedback);
|
||||
|
||||
if (inputCard.VideoDetectedFeedback != null)
|
||||
{
|
||||
VideoInputSyncFeedbacks[inputCard.Number] = new BoolFeedback(() =>
|
||||
{
|
||||
return inputCard.VideoDetectedFeedback.BoolValue;
|
||||
});
|
||||
VideoInputSyncFeedbacks[inputCard.Number] = new BoolFeedback(() => inputCard.VideoDetectedFeedback.BoolValue);
|
||||
}
|
||||
|
||||
InputNameFeedbacks[inputCard.Number] = new StringFeedback(() =>
|
||||
@@ -419,13 +441,10 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
Debug.Console(2, this, "Input Card {0} Name: {1}", inputCard.Number, inputCard.NameFeedback.StringValue);
|
||||
return inputCard.NameFeedback.StringValue;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, this, "Input Card {0} Name is null", inputCard.Number);
|
||||
return "";
|
||||
}
|
||||
Debug.Console(2, this, "Input Card {0} Name is null", inputCard.Number);
|
||||
return "";
|
||||
});
|
||||
|
||||
AddInputCard(inputCard.Number, inputCard);
|
||||
@@ -435,6 +454,9 @@ namespace PepperDash.Essentials.DM
|
||||
Debug.Console(2, this, "***********Input Card of type {0} is cannot be cast as DMInput*************", card.CardInputOutputType);
|
||||
}
|
||||
}
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(NonePortKey, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.None, null, this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -504,13 +526,10 @@ namespace PepperDash.Essentials.DM
|
||||
/// <summary>
|
||||
/// Adds InputPort
|
||||
/// </summary>
|
||||
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType)
|
||||
private 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);
|
||||
AddInputPortWithDebug(cardNum, portName, sigType, portType, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -520,7 +539,10 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
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);
|
||||
var inputPort = new RoutingInputPort(portKey, sigType, portType, Dmps.SwitcherInputs[cardNum], this)
|
||||
{
|
||||
FeedbackMatchObject = Dmps.SwitcherInputs[cardNum]
|
||||
};
|
||||
|
||||
if (cecPort != null)
|
||||
inputPort.Port = cecPort;
|
||||
@@ -528,6 +550,7 @@ namespace PepperDash.Essentials.DM
|
||||
InputPorts.Add(inputPort);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Builds the appropriate ports and calls the appropriate add port method
|
||||
/// </summary>
|
||||
@@ -541,23 +564,23 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
var cecPort = hdmiOutputCard.HdmiOutputPort;
|
||||
|
||||
AddHdmiOutputPort(number, cecPort);
|
||||
AddHdmiOutputPort(number, cecPort);
|
||||
}
|
||||
else if (outputCard is Card.Dmps3HdmiOutputBackend)
|
||||
{
|
||||
var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend;
|
||||
|
||||
var cecPort = hdmiOutputCard.HdmiOutputPort;
|
||||
|
||||
AddHdmiOutputPort(number, cecPort);
|
||||
else if (outputCard is Card.Dmps3HdmiOutputBackend)
|
||||
{
|
||||
var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend;
|
||||
|
||||
var cecPort = hdmiOutputCard.HdmiOutputPort;
|
||||
|
||||
AddHdmiOutputPort(number, cecPort);
|
||||
}
|
||||
else if (outputCard is Card.Dmps3DmOutput)
|
||||
{
|
||||
AddDmOutputPort(number);
|
||||
{
|
||||
AddDmOutputPort(number);
|
||||
}
|
||||
else if (outputCard is Card.Dmps3DmOutputBackend)
|
||||
{
|
||||
AddDmOutputPort(number);
|
||||
else if (outputCard is Card.Dmps3DmOutputBackend)
|
||||
{
|
||||
AddDmOutputPort(number);
|
||||
}
|
||||
else if (outputCard is Card.Dmps3ProgramOutput)
|
||||
{
|
||||
@@ -565,51 +588,51 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
var programOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase);
|
||||
|
||||
DeviceManager.AddDevice(programOutput);
|
||||
DeviceManager.AddDevice(programOutput);
|
||||
}
|
||||
else if (outputCard is Card.Dmps3AuxOutput)
|
||||
{
|
||||
switch (outputCard.CardInputOutputType)
|
||||
{
|
||||
case eCardInputOutputType.Dmps3Aux1Output:
|
||||
else if (outputCard is Card.Dmps3AuxOutput)
|
||||
{
|
||||
switch (outputCard.CardInputOutputType)
|
||||
{
|
||||
case eCardInputOutputType.Dmps3Aux1Output:
|
||||
{
|
||||
AddAudioOnlyOutputPort(number, "Aux1");
|
||||
|
||||
var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase);
|
||||
|
||||
DeviceManager.AddDevice(aux1Output);
|
||||
}
|
||||
break;
|
||||
case eCardInputOutputType.Dmps3Aux2Output:
|
||||
}
|
||||
break;
|
||||
case eCardInputOutputType.Dmps3Aux2Output:
|
||||
{
|
||||
AddAudioOnlyOutputPort(number, "Aux2");
|
||||
|
||||
var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase);
|
||||
|
||||
DeviceManager.AddDevice(aux2Output);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (outputCard is Card.Dmps3CodecOutput)
|
||||
{
|
||||
switch (number)
|
||||
{
|
||||
case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec1:
|
||||
case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec1:
|
||||
case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec1:
|
||||
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec1.ToString());
|
||||
break;
|
||||
case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec2:
|
||||
case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec2:
|
||||
case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec2:
|
||||
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec2.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (outputCard is Card.Dmps3CodecOutput)
|
||||
{
|
||||
switch (number)
|
||||
{
|
||||
case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec1:
|
||||
case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec1:
|
||||
case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec1:
|
||||
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec1.ToString());
|
||||
break;
|
||||
case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec2:
|
||||
case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec2:
|
||||
case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec2:
|
||||
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec2.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (outputCard is Card.Dmps3DialerOutput)
|
||||
{
|
||||
AddAudioOnlyOutputPort(number, "Dialer");
|
||||
AddAudioOnlyOutputPort(number, "Dialer");
|
||||
}
|
||||
else if (outputCard is Card.Dmps3DigitalMixOutput)
|
||||
{
|
||||
@@ -620,11 +643,11 @@ namespace PepperDash.Essentials.DM
|
||||
if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix2
|
||||
|| number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2
|
||||
|| number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2)
|
||||
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString());
|
||||
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString());
|
||||
}
|
||||
else if (outputCard is Card.Dmps3AecOutput)
|
||||
{
|
||||
AddAudioOnlyOutputPort(number, "Aec");
|
||||
AddAudioOnlyOutputPort(number, "Aec");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -638,7 +661,7 @@ namespace PepperDash.Essentials.DM
|
||||
/// <param name="number"></param>
|
||||
void AddAudioOnlyOutputPort(uint number, string portName)
|
||||
{
|
||||
AddOutputPortWithDebug(number, portName, eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, number);
|
||||
AddOutputPortWithDebug(number, portName, eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio, Dmps.SwitcherOutputs[number]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -648,7 +671,7 @@ namespace PepperDash.Essentials.DM
|
||||
/// <param name="cecPort"></param>
|
||||
void AddHdmiOutputPort(uint number, ICec cecPort)
|
||||
{
|
||||
AddOutputPortWithDebug(number, string.Format("hdmiOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, number, cecPort);
|
||||
AddOutputPortWithDebug(number, string.Format("hdmiOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, Dmps.SwitcherOutputs[number], cecPort);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -657,7 +680,7 @@ namespace PepperDash.Essentials.DM
|
||||
/// <param name="number"></param>
|
||||
void AddDmOutputPort(uint number)
|
||||
{
|
||||
AddOutputPortWithDebug(number, string.Format("dmOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, number);
|
||||
AddOutputPortWithDebug(number, string.Format("dmOut{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, Dmps.SwitcherOutputs[number]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -665,9 +688,7 @@ namespace PepperDash.Essentials.DM
|
||||
/// </summary>
|
||||
void AddOutputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector)
|
||||
{
|
||||
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
|
||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this));
|
||||
AddOutputPortWithDebug(cardNum, portName, sigType, portType, selector, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -677,7 +698,10 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
|
||||
Debug.Console(2, this, "Adding output port '{0}'", portKey);
|
||||
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this);
|
||||
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this)
|
||||
{
|
||||
FeedbackMatchObject = Dmps.SwitcherOutputs[cardNum]
|
||||
};
|
||||
|
||||
if (cecPort != null)
|
||||
outputPort.Port = cecPort;
|
||||
@@ -754,13 +778,29 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
else if (args.EventId == DMOutputEventIds.AudioOutEventId)
|
||||
{
|
||||
if (outputCard != null && outputCard.AudioOutFeedback != null)
|
||||
try
|
||||
{
|
||||
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, outputCard.AudioOutFeedback.Number, output);
|
||||
if (outputCard != null && outputCard.AudioOutFeedback != null)
|
||||
{
|
||||
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name,
|
||||
outputCard.AudioOutFeedback.Number, output);
|
||||
}
|
||||
if (AudioOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
AudioOutputFeedbacks[output].FireUpdate();
|
||||
}
|
||||
}
|
||||
if (AudioOutputFeedbacks.ContainsKey(output))
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
AudioOutputFeedbacks[output].FireUpdate();
|
||||
if (outputCard != null)
|
||||
{
|
||||
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name,
|
||||
outputCard.AudioOutSourceFeedback, output);
|
||||
}
|
||||
if (AudioOutputFeedbacks.ContainsKey(output))
|
||||
{
|
||||
AudioOutputFeedbacks[output].FireUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args.EventId == DMOutputEventIds.OutputNameEventId
|
||||
@@ -780,7 +820,7 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
if (RouteOffTimers.ContainsKey(pnt))
|
||||
return;
|
||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(0, pnt.Number, pnt.Type), RouteOffTime);
|
||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(null, pnt.Selector, pnt.Type), RouteOffTime);
|
||||
}
|
||||
|
||||
#region IRouting Members
|
||||
@@ -792,14 +832,32 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType);
|
||||
|
||||
var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail
|
||||
var output = Convert.ToUInt32(outputSelector);
|
||||
//var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail
|
||||
//var output = Convert.ToUInt32(outputSelector);
|
||||
|
||||
if (input <= Dmps.NumberOfSwitcherInputs && output <= Dmps.NumberOfSwitcherOutputs)
|
||||
var input = inputSelector as DMInput;
|
||||
var output = outputSelector as DMOutput;
|
||||
|
||||
if (output == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Warning,
|
||||
"Unable to execute switch for inputSelector {0} to outputSelector {1}", inputSelector,
|
||||
outputSelector);
|
||||
return;
|
||||
}
|
||||
|
||||
var sigTypeIsUsbOrVideo = ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) ||
|
||||
((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) ||
|
||||
((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput);
|
||||
|
||||
if (input == null || (input.Number <= Dmps.NumberOfSwitcherInputs && output.Number <= Dmps.NumberOfSwitcherOutputs &&
|
||||
sigTypeIsUsbOrVideo) ||
|
||||
(input.Number <= Dmps.NumberOfSwitcherInputs + 5 && output.Number <= Dmps.NumberOfSwitcherOutputs &&
|
||||
(sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
|
||||
{
|
||||
// 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)
|
||||
if (input == null)
|
||||
{
|
||||
StartOffTimer(key);
|
||||
}
|
||||
@@ -813,47 +871,53 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
}
|
||||
|
||||
DMInput inCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput;
|
||||
DMOutput outCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput;
|
||||
|
||||
//DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput;
|
||||
|
||||
//if (inCard != null)
|
||||
//{
|
||||
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
|
||||
if ((sigType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
|
||||
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
{
|
||||
|
||||
output.VideoOut = input;
|
||||
}
|
||||
|
||||
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//SystemControl.VideoEnter.BoolValue = true;
|
||||
if (outCard != null)
|
||||
outCard.VideoOut = inCard;
|
||||
output.AudioOut = input;
|
||||
}
|
||||
|
||||
if ((sigType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
if (outCard != null)
|
||||
outCard.AudioOut = inCard;
|
||||
}
|
||||
Debug.Console(1, this, "Routing input {0} audio to output {1}",
|
||||
(eDmps34KAudioOutSource) (input == null ? 0 : input.Number),
|
||||
(CrestronControlSystem.eDmps34K350COutputs) output.Number);
|
||||
|
||||
if ((sigType | eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
|
||||
{
|
||||
if (outCard != null)
|
||||
outCard.USBRoutedTo = inCard;
|
||||
output.AudioOutSource = input == null
|
||||
? eDmps34KAudioOutSource.NoRoute
|
||||
: (eDmps34KAudioOutSource)input.Number;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sigType | eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput)
|
||||
{
|
||||
if (inCard != null)
|
||||
inCard.USBRoutedTo = outCard;
|
||||
}
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Debug.Console(1, this, "Unable to execute route from input {0} to output {1}. Input card not available", inputSelector, outputSelector);
|
||||
//}
|
||||
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
|
||||
{
|
||||
|
||||
output.USBRoutedTo = input;
|
||||
}
|
||||
|
||||
if ((sigType & eRoutingSignalType.UsbInput) != eRoutingSignalType.UsbInput)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (input != null)
|
||||
input.USBRoutedTo = output;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Unable to execute route from input {0} to output {1}", inputSelector, outputSelector);
|
||||
Debug.Console(1, this, "Unable to execute route from input {0} to output {1}", inputSelector,
|
||||
outputSelector);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -862,15 +926,18 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, sigType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector];
|
||||
var output = Dmps.SwitcherOutputs[outputSelector];
|
||||
|
||||
ExecuteSwitch(input, output, sigType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,14 @@ using PepperDash.Essentials.Core.Config;
|
||||
namespace PepperDash.Essentials.DM.Chassis
|
||||
{
|
||||
[Description("Wrapper class for all HdMdNxM4E switchers")]
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingInputsOutputs, IRoutingNumeric, IHasFeedback
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
|
||||
{
|
||||
private HdMdNxM _Chassis;
|
||||
private HdMd4x14kE _Chassis4x1;
|
||||
|
||||
//IroutingNumericEvent
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
public Dictionary<uint, string> InputNames { get; set; }
|
||||
public Dictionary<uint, string> OutputNames { get; set; }
|
||||
|
||||
@@ -70,26 +73,34 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
var inputName = InputNames[i];
|
||||
_Chassis.Inputs[i].Name.StringValue = inputName;
|
||||
var index = i;
|
||||
var inputName = InputNames[index];
|
||||
_Chassis.Inputs[index].Name.StringValue = inputName;
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, i, this));
|
||||
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[i].VideoDetectedFeedback.BoolValue));
|
||||
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[i].Name.StringValue));
|
||||
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[i].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiInputs[index]
|
||||
});
|
||||
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
|
||||
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue));
|
||||
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
var outputName = OutputNames[i];
|
||||
var index = i;
|
||||
var outputName = OutputNames[index];
|
||||
_Chassis.Outputs[i].Name.StringValue = outputName;
|
||||
|
||||
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, i, this));
|
||||
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[i].VideoOutFeedback.Number));
|
||||
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[i].Name.StringValue));
|
||||
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[i].VideoOutFeedback.NameFeedback.StringValue));
|
||||
eRoutingPortConnectionType.Hdmi, index, this)
|
||||
{
|
||||
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
|
||||
});
|
||||
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
|
||||
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue));
|
||||
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
|
||||
}
|
||||
|
||||
_Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange);
|
||||
@@ -102,6 +113,16 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
private void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
|
||||
public void EnableHdcp(uint port)
|
||||
{
|
||||
if (port > _Chassis.NumberOfInputs) return;
|
||||
@@ -328,44 +349,45 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
|
||||
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
if (!args.DeviceOnLine) return;
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
{
|
||||
_Chassis.Inputs[i].Name.StringValue = InputNames[i];
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
_Chassis.Inputs[i].Name.StringValue = InputNames[i];
|
||||
}
|
||||
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
|
||||
{
|
||||
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
feedback.FireUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
if (args.EventId == DMOutputEventIds.VideoOutEventId)
|
||||
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
|
||||
|
||||
for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++)
|
||||
{
|
||||
foreach (var item in VideoOutputRouteFeedbacks)
|
||||
{
|
||||
item.FireUpdate();
|
||||
}
|
||||
var index = i;
|
||||
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback);
|
||||
var localOutputPort =
|
||||
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]);
|
||||
|
||||
|
||||
VideoOutputRouteFeedbacks[i].FireUpdate();
|
||||
OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo));
|
||||
}
|
||||
}
|
||||
|
||||
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
|
||||
{
|
||||
if (args.EventId == DMInputEventIds.VideoDetectedEventId)
|
||||
if (args.EventId != DMInputEventIds.VideoDetectedEventId) return;
|
||||
foreach (var item in VideoInputSyncFeedbacks)
|
||||
{
|
||||
foreach (var item in VideoInputSyncFeedbacks)
|
||||
{
|
||||
item.FireUpdate();
|
||||
}
|
||||
item.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
@@ -14,15 +15,19 @@ using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Essentials.Core.DeviceInfo;
|
||||
|
||||
namespace PepperDash.Essentials.DM.Endpoints.DGEs
|
||||
{
|
||||
[Description("Wrapper class for DGE-100")]
|
||||
public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec
|
||||
public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec, IDeviceInfoProvider
|
||||
{
|
||||
private const int CtpPort = 41795;
|
||||
private readonly Dge100 _dge;
|
||||
|
||||
private readonly TsxCcsUcCodec100EthernetReservedSigs _dgeEthernetInfo;
|
||||
|
||||
public BasicTriListWithSmartObject Panel { get { return _dge; } }
|
||||
|
||||
private DeviceConfig _dc;
|
||||
@@ -32,7 +37,14 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
|
||||
public Dge100Controller(string key, string name, Dge100 device, DeviceConfig dc, CrestronTouchpanelPropertiesConfig props)
|
||||
:base(key, name, device)
|
||||
{
|
||||
_dge = device;
|
||||
_dge = device;
|
||||
_dgeEthernetInfo = _dge.ExtenderEthernetReservedSigs;
|
||||
//_dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo();
|
||||
_dgeEthernetInfo.Use();
|
||||
|
||||
DeviceInfo = new DeviceInfo();
|
||||
|
||||
_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
|
||||
|
||||
_dc = dc;
|
||||
|
||||
@@ -69,8 +81,113 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
|
||||
|
||||
#region ICec Members
|
||||
public Cec StreamCec { get { return _dge.HdmiOut.StreamCec; } }
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IDeviceInfoProvider
|
||||
|
||||
public DeviceInfo DeviceInfo { get; private set; }
|
||||
|
||||
public event DeviceInfoChangeHandler DeviceInfoChanged;
|
||||
|
||||
public void UpdateDeviceInfo()
|
||||
{
|
||||
DeviceInfo.IpAddress = _dgeEthernetInfo.IpAddressFeedback.StringValue;
|
||||
DeviceInfo.MacAddress = _dgeEthernetInfo.MacAddressFeedback.StringValue;
|
||||
|
||||
GetFirmwareAndSerialInfo();
|
||||
|
||||
OnDeviceInfoChange();
|
||||
}
|
||||
|
||||
private void GetFirmwareAndSerialInfo()
|
||||
{
|
||||
if (String.IsNullOrEmpty(_dgeEthernetInfo.IpAddressFeedback.StringValue))
|
||||
{
|
||||
Debug.Console(1, this, "IP Address information not yet received. No device is online");
|
||||
return;
|
||||
}
|
||||
|
||||
var tcpClient = new GenericTcpIpClient("", _dgeEthernetInfo.IpAddressFeedback.StringValue, CtpPort, 1024){AutoReconnect = false};
|
||||
|
||||
var gather = new CommunicationGather(tcpClient, "\r\n\r\n");
|
||||
|
||||
tcpClient.ConnectionChange += (sender, args) =>
|
||||
{
|
||||
if (!args.Client.IsConnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
args.Client.SendText("ver\r\n");
|
||||
};
|
||||
|
||||
gather.LineReceived += (sender, args) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "{0}", args.Text);
|
||||
|
||||
if (args.Text.ToLower().Contains("host"))
|
||||
{
|
||||
DeviceInfo.HostName = args.Text.Split(':')[1].Trim();
|
||||
|
||||
Debug.Console(1, this, "hostname: {0}", DeviceInfo.HostName);
|
||||
tcpClient.Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
//ignore console prompt
|
||||
/*if (args.Text.ToLower().Contains(">"))
|
||||
{
|
||||
Debug.Console(1, this, "Ignoring console");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Text.ToLower().Contains("dge"))
|
||||
{
|
||||
Debug.Console(1, this, "Ignoring DGE");
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (!args.Text.Contains('['))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var splitResponse = args.Text.Split('[');
|
||||
|
||||
foreach (string t in splitResponse)
|
||||
{
|
||||
Debug.Console(1, this, "{0}", t);
|
||||
}
|
||||
|
||||
DeviceInfo.SerialNumber = splitResponse[1].Split(' ')[4].Replace("#", "");
|
||||
DeviceInfo.FirmwareVersion = splitResponse[1].Split(' ')[0];
|
||||
|
||||
Debug.Console(1, this, "Firmware: {0} SerialNumber: {1}", DeviceInfo.FirmwareVersion,
|
||||
DeviceInfo.SerialNumber);
|
||||
|
||||
tcpClient.SendText("host\r\n");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, this, "Exception getting data: {0}", ex.Message);
|
||||
Debug.Console(0, this, "response: {0}", args.Text);
|
||||
}
|
||||
};
|
||||
|
||||
tcpClient.Connect();
|
||||
}
|
||||
|
||||
private void OnDeviceInfoChange()
|
||||
{
|
||||
var handler = DeviceInfoChanged;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(this, new DeviceInfoEventArgs(DeviceInfo));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class Dge100ControllerFactory : EssentialsDeviceFactory<Dge100Controller>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user