Compare commits

..

42 Commits

Author SHA1 Message Date
Andrew Welker
c452ef90bb add QR checksum back 2020-11-20 12:40:33 -07:00
Andrew Welker
f3ddce99d5 got it building... 2020-11-19 14:16:34 -07:00
Andrew Welker
ef215e8b16 more updates 2020-11-19 12:11:23 -07:00
Andrew Welker
19f39d7373 more updates and moves 2020-11-19 12:11:12 -07:00
Andrew Welker
58f88037f5 getting project files correct 2020-11-19 10:58:38 -07:00
Andrew Welker
8821bffee7 more moving things 2020-11-19 10:57:08 -07:00
Andrew Welker
63bd25c0e1 moving things around 2020-11-19 10:57:00 -07:00
Andrew Welker
febef3f5b1 getting closer... 2020-11-19 10:52:47 -07:00
Andrew Welker
e3d9f6be6e getting refs right 2020-11-19 10:48:43 -07:00
Andrew Welker
d18a099fe4 fixing cisco class 2020-11-19 10:00:20 -07:00
Andrew Welker
64c233e36b fixing things 2020-11-19 09:56:48 -07:00
Andrew Welker
8244b6f02f add missing files 2020-11-19 09:44:56 -07:00
Andrew Welker
c2ee9be9fe add files that didn't come through in the rebase 2020-11-19 09:14:40 -07:00
Andrew Welker
89952f3d37 fixing some namespace issues 2020-11-19 09:13:34 -07:00
Andrew Welker
7b3ef897fb updates to get things back working 2020-11-19 08:00:17 -07:00
Andrew Welker
97995df962 refactoring and cleanup 2020-11-18 15:37:08 -07:00
Andrew Welker
c1381acc92 made config publicly accessible 2020-11-18 15:25:02 -07:00
Andrew Welker
edb3c70d27 add comm monitor for fusion stuff 2020-11-18 15:25:02 -07:00
Andrew Welker
21b8a86d21 getting asset created 2020-11-18 15:25:02 -07:00
Andrew Welker
374ce13add updates for dual-display Fusion 2020-11-18 15:25:02 -07:00
Andrew Welker
3856a96e5f add dual display fusion controller 2020-11-18 15:25:01 -07:00
Andrew Welker
6b8aa0afe6 refactoring Fusion room classes
added DualDisplay Fusion support
2020-11-18 15:23:27 -07:00
Andrew Welker
153c7f2409 add dual display room and config 2020-11-18 15:14:23 -07:00
Andrew Welker
4fa9e6ba17 modify VTC1 room class to work with modified base class 2020-11-18 15:14:23 -07:00
Andrew Welker
c5b51c8976 renamed room folder -> rooms 2020-11-18 15:14:23 -07:00
Andrew Welker
6d27faa918 renamed room -> rooms
started on Dual Display room;
2020-11-18 15:14:23 -07:00
Andrew Welker
7a1aec5dfc files moving around 2020-11-18 15:14:22 -07:00
Andrew Welker
3262b491c9 reorganizing devices folder 2020-11-18 15:11:40 -07:00
Andrew Welker
cb4a8640f0 Got things moved successfully 2020-11-18 15:11:39 -07:00
Andrew Welker
fcb2f88be7 moving interfaces and base classes into Core from Devices Common
maybe too far down the rabbit hole?
2020-11-18 15:07:55 -07:00
Andrew Welker
6f5a4f17fa refactoring and more refactoring 2020-11-18 14:45:21 -07:00
Andrew Welker
c5aa8d29cb refactoring room classes 2020-11-18 14:38:13 -07:00
Andrew Welker
18a362f979 temporarily suppressing some compile errors 2020-11-18 14:37:03 -07:00
Andrew Welker
20257e425e Refactoring things to base class 2020-11-18 14:37:03 -07:00
Andrew Welker
38adaf623f update config with DestinationList 2020-11-18 14:32:53 -07:00
Andrew Welker
6f300402aa added classes for support of destination lists in configuration. 2020-11-18 14:32:52 -07:00
Andrew Welker
f01ed3d876 some refactoring and formatting 2020-11-18 14:32:52 -07:00
Andrew Welker
878e5ab9fb refactoring and cleanup 2020-11-18 14:32:52 -07:00
Andrew Welker
43e39a5222 refactoring and cleanup 2020-11-18 14:32:28 -07:00
Andrew Welker
e84423eb64 cleanup VtcRoom 2020-11-18 14:30:46 -07:00
Andrew Welker
013bcfd9d4 Cleanup for EssentialHuddleSpaceRoom 2020-11-18 14:29:36 -07:00
Andrew Welker
78f4cd6abe Cleanup for EssentialsRoomBase 2020-11-18 14:29:00 -07:00
372 changed files with 25718 additions and 43221 deletions

View File

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

View File

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

View File

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

View File

@@ -8,9 +8,12 @@ on:
- bugfix/*
- release/*
- development
pull_request:
branches:
- development
env:
# solution path doesn't need slashes unless it is multiple folders deep
# solution path doesn't need slashes unless there it is multiple folders deep
# solution name does not include extension. .sln is assumed
SOLUTION_PATH: PepperDashEssentials
SOLUTION_FILE: PepperDashEssentials
@@ -22,7 +25,7 @@ env:
RELEASE_BRANCH: main
jobs:
Build_Project:
runs-on: windows-2019
runs-on: windows-latest
steps:
# First we checkout the source repo
- name: Checkout repo
@@ -75,9 +78,16 @@ 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 }}
@@ -87,6 +97,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload the build package to the release
- name: Upload Release Package
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
id: upload_release
uses: actions/upload-release-asset@v1
with:
@@ -98,7 +109,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-2019
runs-on: windows-latest
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1
@@ -139,3 +150,160 @@ 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"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
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"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Create new branch
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- name: Copy Files to root & delete output directory
run: |
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
Remove-Item -Path .\output -Recurse
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: |
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
Write-Host "Branch: $branch"
git push -u origin $($branch) --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./

View File

@@ -19,7 +19,7 @@ env:
RELEASE_BRANCH: main
jobs:
Build_Project:
runs-on: windows-2019
runs-on: windows-latest
steps:
# First we checkout the source repo
- name: Checkout repo
@@ -82,7 +82,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-2019
runs-on: windows-latest
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1
@@ -123,3 +123,148 @@ 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"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
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"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
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
View File

@@ -388,4 +388,3 @@ 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.

View File

@@ -55,7 +55,7 @@ namespace PepperDash.Essentials
return null;
}
// DSP/DMPS format: deviceKey--levelName, biampTesira-1--master
// DSP format: deviceKey--levelName, biampTesira-1--master
match = Regex.Match(DeviceKey, @"([-_\w]+)--(.+)");
if (match.Success)
{
@@ -67,27 +67,6 @@ namespace PepperDash.Essentials
if (dsp.LevelControlPoints.ContainsKey(levelTag)) // should always...
return dsp.LevelControlPoints[levelTag];
}
var dmps = DeviceManager.GetDeviceForKey(devKey) as DmpsAudioOutputController;
if (dmps != null)
{
var levelTag = match.Groups[2].Value;
switch (levelTag)
{
case "master":
return dmps.MasterVolumeLevel;
case "source":
return dmps.SourceVolumeLevel;
case "micsmaster":
return dmps.MicsMasterVolumeLevel;
case "codec1":
return dmps.Codec1VolumeLevel;
case "codec2":
return dmps.Codec2VolumeLevel;
default:
return dmps.MasterVolumeLevel;
}
}
// No volume for some reason. We have failed as developers
return null;
}

View File

@@ -70,14 +70,6 @@ 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
@@ -123,8 +115,6 @@ 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
@@ -155,8 +145,6 @@ 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;
}

View File

@@ -13,11 +13,9 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Fusion;
using PepperDash.Essentials.Core.Web;
using PepperDash.Essentials.Core.Rooms.Config;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Config;
using Newtonsoft.Json;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
@@ -29,7 +27,6 @@ namespace PepperDash.Essentials
HttpLogoServer LogoServer;
private CTimer _startTimer;
private CEvent _initializeEvent;
private const long StartupTime = 500;
public ControlSystem()
@@ -38,7 +35,6 @@ namespace PepperDash.Essentials
Thread.MaxNumberOfUserThreads = 400;
Global.ControlSystem = this;
DeviceManager.Initialize(this);
SecretsManager.Initialize();
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
}
@@ -47,75 +43,51 @@ namespace PepperDash.Essentials
/// </summary>
public override void InitializeSystem()
{
// If the control system is a DMPS type, we need to wait to exit this method until all devices have had time to activate
// to allow any HD-BaseT DM endpoints to register first.
bool preventInitializationComplete = Global.ControlSystemIsDmpsType;
if (preventInitializationComplete)
{
Debug.Console(1, "******************* InitializeSystem() Entering **********************");
_startTimer = new CTimer(StartSystem, preventInitializationComplete, StartupTime);
_initializeEvent = new CEvent(true, false);
DeviceManager.AllDevicesRegistered += (o, a) =>
{
_initializeEvent.Set();
};
_initializeEvent.Wait(30000);
Debug.Console(1, "******************* InitializeSystem() Exiting **********************");
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
}
else
{
_startTimer = new CTimer(StartSystem, preventInitializationComplete, StartupTime);
}
_startTimer = new CTimer(StartSystem,StartupTime);
}
private void StartSystem(object preventInitialization)
private void StartSystem(object obj)
{
DeterminePlatform();
if (Debug.DoNotLoadOnNextBoot)
{
CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file",
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
ConsoleAccessLevelEnum.AccessOperator);
}
CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(BridgeHelper.JoinmapMarkdown, "getjoinmapmarkdown"
, "generate markdown of map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s), "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s);
}, "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}{1}", tl, CrestronEnvironment.NewLine);
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse
("Current running configuration. This is the merged system and template configuration" + CrestronEnvironment.NewLine);
("Current running configuration. This is the merged system and template configuration");
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
CrestronConsole.ConsoleCommandResponse(
"This system can be found at the following URLs:{2}" +
"System URL: {0}{2}" +
"Template URL: {1}{2}",
ConfigReader.ConfigObject.SystemUrl,
ConfigReader.ConfigObject.TemplateUrl,
CrestronEnvironment.NewLine),
"portalinfo",
"Shows portal URLS from configuration",
ConsoleAccessLevelEnum.AccessOperator);
{
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(DeviceManager.GetRoutingPorts,
@@ -127,10 +99,7 @@ namespace PepperDash.Essentials
return;
}
if (!(bool)preventInitialization)
{
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
}
SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
}
/// <summary>
@@ -160,53 +129,34 @@ namespace PepperDash.Essentials
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
{
string userFolder;
string nvramFolder;
bool is4series = false;
if (eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4)) // Handle 4-series
{
is4series = true;
// Set path to user/
userFolder = "user";
nvramFolder = "nvram";
}
else
{
userFolder = "User";
nvramFolder = "Nvram";
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, is4series ? "4-series" : "3-series");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion);
// Check if User/ProgramX exists
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + userFolder
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
{
Debug.Console(0, @"{0}/program{1} directory found", userFolder, InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + userFolder
Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "User"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
}
// Check if Nvram/Programx exists
else if (Directory.Exists(directoryPrefix + dirSeparator + nvramFolder
else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber)))
{
Debug.Console(0, @"{0}/program{1} directory found", nvramFolder, InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + nvramFolder
Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "Nvram"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
}
// If neither exists, set path to User/ProgramX
else
{
Debug.Console(0, @"No previous directory found. Using {0}/program{1}", userFolder, InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + userFolder
Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber);
filePathPrefix = directoryPrefix + dirSeparator + "User"
+ dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator;
}
}
else // Handles Linux OS (Virtual Control)
{
Debug.SetDebugLevel(2);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", Global.AssemblyVersion);
// Set path to User/
@@ -308,10 +258,6 @@ namespace PepperDash.Essentials
if (!Directory.Exists(pluginDir))
Directory.Create(pluginDir);
var joinmapDir = Global.FilePathPrefix + "joinmaps";
if(!Directory.Exists(joinmapDir))
Directory.Create(joinmapDir);
return configExists;
}
@@ -359,7 +305,6 @@ namespace PepperDash.Essentials
// Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
DeviceManager.AddDevice(new EssemtialsWebApi("essentialsWebApi","Essentials Web API"));
// Add global System Monitor device
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
@@ -377,12 +322,7 @@ namespace PepperDash.Essentials
// Skip this to prevent unnecessary warnings
if (devConf.Key == "processor")
{
var prompt = Global.ControlSystem.ControllerPrompt;
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) ||
String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase);
if (!typeMatch)
if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower())
Debug.Console(0,
"WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available",
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
@@ -397,7 +337,9 @@ namespace PepperDash.Essentials
if(propertiesConfig == null)
propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig();
DeviceManager.AddDevice(DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig));
var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig);
DeviceManager.AddDevice(dmpsRoutingController);
}
else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
{
@@ -435,11 +377,11 @@ namespace PepperDash.Essentials
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
}
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded.");
@@ -484,94 +426,56 @@ namespace PepperDash.Essentials
return;
}
uint fusionIpId = 0xf1;
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as IEssentialsRoom;
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
if (room != null)
{
// default to no join map key
string fusionJoinMapKey = string.Empty;
if (room.Config.Properties["fusion"] != null)
if (room is EssentialsHuddleSpaceRoom)
{
Debug.Console(2, "Custom Fusion config found. Using custom values");
DeviceManager.AddDevice(room);
var fusionConfig = room.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
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));
if (fusionConfig != null)
{
fusionIpId = fusionConfig.IpIdInt;
fusionJoinMapKey = fusionConfig.JoinMapKey;
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
}
else if (room is EssentialsHuddleVtc1Room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
AddRoomAndBuildMC(room);
if (room is IEssentialsHuddleSpaceRoom)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
}
else if (room is IEssentialsHuddleVtc1Room)
{
if (!(room is EssentialsCombinedHuddleVtc1Room))
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
}
}
else if (room is EssentialsTechRoom)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice,
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
}
fusionIpId += 1;
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
}
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded.");
}
private static void AddRoomAndBuildMC(IEssentialsRoom room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
CreateMobileControlBridge(room);
}
private static void CreateMobileControlBridge(object room)
private static void CreateMobileControlBridge(EssentialsRoomBase room)
{
var mobileControl = GetMobileControlDevice();
if (mobileControl == null) return;
var mobileControl3 = mobileControl as IMobileControl3;
if (mobileControl3 != null)
{
mobileControl3.CreateMobileControlRoomBridge(room as IEssentialsRoom, mobileControl);
}
else
{
mobileControl.CreateMobileControlRoomBridge(room as EssentialsRoomBase, mobileControl);
}
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
}
@@ -632,31 +536,23 @@ namespace PepperDash.Essentials
string logoLight = null;
string logo = null;
try
if (c.Properties["logoDark"] != null)
{
if (c.Properties["logoDark"] != null)
{
logoDark = c.Properties["logoDark"].Value<string>("type");
}
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"));
logoDark = c.Properties["logoDark"].Value<string>("type");
}
catch
if (c.Properties["logoLight"] != null)
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config");
return false;
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"));
}
}
}

View File

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

View File

@@ -11,7 +11,7 @@ using PepperDash.Essentials.Core.Routing;
namespace PepperDash.Essentials
{
public class Amplifier : EssentialsDevice, IRoutingSinkNoSwitching
public class Amplifier : EssentialsDevice, IRoutingSink
{
public event SourceInfoChangeHandler CurrentSourceChange;

View File

@@ -88,7 +88,7 @@
{
"name": "Wireless Video",
"key": "wePresent-1",
"type": "genericSource",
"type": "wePresent",
"group": "genericSource",
"uid": 9,
"properties": {

View File

@@ -114,7 +114,7 @@
{
"name": "Wireless Video",
"key": "wePresent-1",
"type": "genericSource",
"type": "wePresent",
"properties": {},
"group": "genericSource",
"uid": 3

View File

@@ -1,358 +1,429 @@
using System;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.Fusion;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Fusion;
namespace PepperDash.Essentials.Fusion
{
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
{
BooleanSigData CodecIsInCall;
public EssentialsHuddleVtc1FusionController(IEssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
: base(room, ipId, joinMapKey)
{
}
/// <summary>
/// Called in base class constructor before RVI and GUID files are built
/// </summary>
protected override void ExecuteCustomSteps()
{
SetUpCodec();
}
/// <summary>
/// Creates a static asset for the codec and maps the joins to the main room symbol
/// </summary>
void SetUpCodec()
{
try
{
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
if (codec == null)
{
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
return;
}
codec.UsageTracker = new UsageTracking(codec);
codec.UsageTracker.UsageIsTracked = true;
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
// Map FusionRoom Attributes:
// Codec volume
var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig);
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
// In Call Status
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly);
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
// Online status
if (codec is ICommunicationMonitor)
{
var c = codec as ICommunicationMonitor;
var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.AttributeName, eSigIoMask.InputSigOnly);
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
c.CommunicationMonitor.StatusChange += (o, a) =>
{
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
};
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.AttributeName);
}
// Codec IP Address
bool codecHasIpInfo = false;
var codecComm = codec.Communication;
string codecIpAddress = string.Empty;
int codecIpPort = 0;
StringSigData codecIpAddressSig;
StringSigData codecIpPortSig;
if(codecComm is GenericSshClient)
{
codecIpAddress = (codecComm as GenericSshClient).Hostname;
codecIpPort = (codecComm as GenericSshClient).Port;
codecHasIpInfo = true;
}
else if (codecComm is GenericTcpIpClient)
{
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
codecIpPort = (codecComm as GenericTcpIpClient).Port;
codecHasIpInfo = true;
}
if (codecHasIpInfo)
{
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
var tempAsset = new FusionAsset();
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
// TODO: Map relevant attributes on asset symbol
codecAsset.TrySetMakeModel(codec);
codecAsset.TryLinkAssetErrorToCommunication(codec);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
}
}
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
{
var codec = (Room as IEssentialsHuddleVtc1Room).VideoCodec;
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
}
// These methods are overridden because they access the room class which is of a different type
protected override void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.Console(0, this, "Creating Fusion Room symbol with GUID: {0} and IP-ID {1:X2}", RoomGuid, ipId);
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
FusionRoom.Register();
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
// Room to fusion room
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
(Room as IEssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as IEssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
}
protected override void SetUpSources()
{
// Sources
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as IEssentialsHuddleVtc1Room).SourceListKey);
if (dict != null)
{
// NEW PROCESS:
// Make these lists and insert the fusion attributes by iterating these
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
uint i = 1;
foreach (var kvp in setTopBoxes)
{
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
break;
}
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
i = 1;
foreach (var kvp in discPlayers)
{
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
}
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
i = 1;
foreach (var kvp in laptops)
{
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
break;
}
foreach (var kvp in dict)
{
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
if (usageDevice != null)
{
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
usageDevice.UsageTracker.UsageIsTracked = true;
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
}
}
else
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
(Room as IEssentialsHuddleVtc1Room).SourceListKey, Room.Key);
}
}
protected override void SetUpDisplay()
{
try
{
//Setup Display Usage Monitoring
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
// Consider updating this in multiple display systems
foreach (DisplayBase display in displays)
{
display.UsageTracker = new UsageTracking(display);
display.UsageTracker.UsageIsTracked = true;
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
}
var defaultDisplay = (Room as IEssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
if (defaultDisplay == null)
{
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
return;
}
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
// Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
var defaultDisplayTwoWay = defaultDisplay as IHasPowerControlWithFeedback;
if (defaultDisplayTwoWay != null)
{
defaultDisplayTwoWay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
}
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
var tempAsset = new FusionAsset();
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
if (defaultTwoWayDisplay != null)
{
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
}
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
}
}
protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
{
string displayName = string.Format("Display {0} - ", displayIndex);
if (display == (Room as IEssentialsHuddleVtc1Room).DefaultDisplay)
{
// Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
// Power Off
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
var displayTwoWay = display as IHasPowerControlWithFeedback;
if (displayTwoWay != null)
{
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
}
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as IEssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
}
}
}
using System;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.Fusion;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Fusion;
namespace PepperDash.Essentials.Fusion
{
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
{
private BooleanSigData _codecIsInCall;
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
: base(room, ipId)
{
}
/// <summary>
/// Called in base class constructor before RVI and GUID files are built
/// </summary>
protected override void ExecuteCustomSteps()
{
SetUpCodec();
}
/// <summary>
/// Creates a static asset for the codec and maps the joins to the main room symbol
/// </summary>
private void SetUpCodec()
{
try
{
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
{
return;
}
var codec = essentialsHuddleVtc1Room.VideoCodec;
if (codec == null)
{
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
return;
}
codec.UsageTracker = new UsageTracking(codec) {UsageIsTracked = true};
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var codecPowerOnAction = new Action<bool>(b =>
{
if (!b)
{
codec.StandbyDeactivate();
}
});
var codecPowerOffAction = new Action<bool>(b =>
{
if (!b)
{
codec.StandbyActivate();
}
});
// Map FusionRoom Attributes:
// Codec volume
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", 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);
codec.CallStatusChange += codec_CallStatusChange;
// Online status
if (codec is ICommunicationMonitor)
{
var c = codec as ICommunicationMonitor;
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", 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");
}
// Codec IP Address
bool codecHasIpInfo = false;
var codecComm = codec.Communication;
string codecIpAddress = string.Empty;
int codecIpPort = 0;
if (codecComm is GenericSshClient)
{
codecIpAddress = (codecComm as GenericSshClient).Hostname;
codecIpPort = (codecComm as GenericSshClient).Port;
codecHasIpInfo = true;
}
else if (codecComm is GenericTcpIpClient)
{
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
codecIpPort = (codecComm as GenericTcpIpClient).Port;
codecHasIpInfo = true;
}
if (codecHasIpInfo)
{
StringSigData codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC",
eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
StringSigData codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC",
eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
FusionAsset tempAsset;
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name,
"Codec", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
// TODO: Map relevant attributes on asset symbol
codecAsset.TrySetMakeModel(codec);
codecAsset.TryLinkAssetErrorToCommunication(codec);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
}
}
private void codec_CallStatusChange(object sender, Core.Devices.Codec.CodecCallStatusItemChangeEventArgs e)
{
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
{
return;
}
var codec = essentialsHuddleVtc1Room.VideoCodec;
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
}
// These methods are overridden because they access the room class which is of a different type
protected override void CreateSymbolAndBasicSigs(uint ipId)
{
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
FusionRoom.Register();
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange +=
FusionRoomSchedule_DeviceExtenderSigChange;
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange +=
ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule",
"Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod",
"Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting",
"Creates and Ad Hoc meeting for on hour or until the next meeting",
ConsoleAccessLevelEnum.AccessOperator);
// Room to fusion room
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source",
eSigIoMask.InputSigOnly);
// Don't think we need to get current status of this as nothing should be alive yet.
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room != null)
{
essentialsHuddleVtc1Room.CurrentSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(
essentialsHuddleVtc1Room.PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(
() => essentialsHuddleVtc1Room.RunRouteAction("roomOff", Room.SourceListKey));
}
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
}
protected override void SetUpSources()
{
// Sources
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
{
return;
}
var dict = ConfigReader.ConfigObject.GetSourceListForKey(essentialsHuddleVtc1Room.SourceListKey);
if (dict != null)
{
// NEW PROCESS:
// Make these lists and insert the fusion attributes by iterating these
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
uint i = 1;
foreach (var kvp in setTopBoxes)
{
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
{
break;
}
}
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
i = 1;
foreach (var kvp in discPlayers)
{
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
{
break;
}
}
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
i = 1;
foreach (var kvp in laptops)
{
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 10) // We only have ten spots???
{
break;
}
}
foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType<IUsageTracking>())
{
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) {UsageIsTracked = true};
usageDevice.UsageTracker.DeviceUsageEnded +=
UsageTracker_DeviceUsageEnded;
}
}
else
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
essentialsHuddleVtc1Room.SourceListKey, Room.Key);
}
}
protected override void SetUpDisplay()
{
try
{
//Setup Display Usage Monitoring
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
// Consider updating this in multiple display systems
foreach (var display in displays.Cast<DisplayBase>())
{
display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
display.UsageTracker.DeviceUsageEnded +=
UsageTracker_DeviceUsageEnded;
}
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
{
return;
}
var defaultDisplay = essentialsHuddleVtc1Room.DefaultDisplay as TwoWayDisplayBase;
if (defaultDisplay == null)
{
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
return;
}
var dispPowerOnAction = new Action<bool>(b =>
{
if (!b)
{
defaultDisplay.PowerOn();
}
});
var dispPowerOffAction = new Action<bool>(b =>
{
if (!b)
{
defaultDisplay.PowerOff();
}
});
// Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
{
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
}
MapDisplayToRoomJoins(1, 158, defaultDisplay);
var deviceConfig =
ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
FusionAsset tempAsset;
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
defaultDisplay.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
}
}
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, TwoWayDisplayBase display)
{
var displayName = string.Format("Display {0} - ", displayIndex);
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null || display != essentialsHuddleVtc1Room.DefaultDisplay)
{
return;
}
// 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
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);
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b =>
{
if (b)
{
return;
}
var huddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (huddleVtc1Room != null)
{
huddleVtc1Room.RunRouteAction("roomOff", Room.SourceListKey);
}
});
}
}
}

View File

@@ -1,106 +0,0 @@
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);
}
}
}
}

View File

@@ -129,29 +129,10 @@
<Compile Include="Bridges\JoinMaps\SetTopBoxControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
<Compile Include="ControlSystem.cs" />
<Compile Include="Factory\DeviceFactory.cs" />
<Compile Include="Devices\Amplifier.cs" />
<Compile Include="ControlSystem.cs" />
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
<Compile Include="Fusion\EssentialsTechRoomFusionSystemController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\SimplRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
<Compile Include="Room\Config\EssentialsTechRoomConfig.cs" />
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
<Compile Include="Room\Types\EssentialsCombinedHuddleVtc1Room.cs" />
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleSpaceRoom.cs" />
<Compile Include="Room\Types\Interfaces\IEssentialsHuddleVtc1Room.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
@@ -181,7 +162,6 @@
<Compile Include="UI\JoinConstants\UIBoolJoin.cs" />
<Compile Include="UI\DualDisplaySourceSRLController.cs" />
<Compile Include="UI\SubpageReferenceListActivityItem.cs" />
<Compile Include="Room\Types\EssentialsHuddleSpaceRoom.cs" />
<Compile Include="UI\EssentialsTouchpanelController.cs" />
<Compile Include="UI\SubpageReferenceListSourceItem.cs" />
<None Include="app.config" />
@@ -222,6 +202,9 @@
<Name>PepperDash_Essentials_DM</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="UIDrivers\EssentialsDualDisplay\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ControlSystem>
<Name>Test RMC3</Name>
<Address>auto 192.168.1.40;username crestron</Address>
<Name>192.168.10.1</Name>
<Address>auto 192.168.10.1</Address>
<ProgramSlot>Program01</ProgramSlot>
<Storage>Internal Flash</Storage>
</ControlSystem>

View File

@@ -8,19 +8,19 @@ using Newtonsoft.Json;
namespace PepperDash.Essentials.Room.Config
{
public class SimplRoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
{
[JsonProperty("roomPhoneNumber")]
public string RoomPhoneNumber { get; set; }
[JsonProperty("roomURI")]
public string RoomURI { get; set; }
[JsonProperty("speedDials")]
public List<SimplSpeedDial> SpeedDials { get; set; }
public List<DDVC01SpeedDial> SpeedDials { get; set; }
[JsonProperty("volumeSliderNames")]
public List<string> VolumeSliderNames { get; set; }
}
public class SimplSpeedDial
public class DDVC01SpeedDial
{
[JsonProperty("name")]
public string Name { get; set; }

View File

@@ -19,48 +19,40 @@ namespace PepperDash.Essentials.Room.Config
/// Returns a room object from this config data
/// </summary>
/// <returns></returns>
public static IKeyed GetRoomObject(DeviceConfig roomConfig)
public static Device GetRoomObject(DeviceConfig roomConfig)
{
var typeName = roomConfig.Type.ToLower();
if (typeName == "huddle")
{
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
switch (typeName)
{
case "huddle" :
{
return new EssentialsHuddleSpaceRoom(roomConfig);
}
case "huddlevtc1" :
{
return new EssentialsHuddleVtc1Room(roomConfig);
}
case "ddvc01bridge" :
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
case "dualdisplay" :
{
return new EssentialsDualDisplayRoom(roomConfig);
}
case "combinedhuddlevtc1" :
{
return new EssentialsCombinedHuddleVtc1Room(roomConfig);
}
case "techroom" :
{
return new EssentialsTechRoom(roomConfig);
}
default :
{
return Core.DeviceFactory.GetDevice(roomConfig);
}
}
return huddle;
}
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);
return rm;
}
return null;
}
/// <summary>
/// Gets and operating, standalone emergegncy object that can be plugged into a room.
/// Returns null if there is no emergency defined
/// </summary>
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, IEssentialsRoom room)
public static EssentialsRoomEmergencyBase GetEmergency(EssentialsRoomPropertiesConfig props, EssentialsRoomBase room)
{
// This emergency
var emergency = props.Emergency;
@@ -109,7 +101,7 @@ namespace PepperDash.Essentials.Room.Config
if (behaviour == "trackroomstate")
{
// Tie LED enable to room power state
var essRoom = room as IEssentialsRoom;
var essRoom = room as EssentialsRoomBase;
essRoom.OnFeedback.OutputChange += (o, a) =>
{
if (essRoom.OnFeedback.BoolValue)
@@ -160,24 +152,6 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("helpMessage")]
public string HelpMessage { get; set; }
/// <summary>
/// Read this value to get the help message. It checks for the old and new config format.
/// </summary>
public string HelpMessageForDisplay
{
get
{
if(Help != null && !string.IsNullOrEmpty(Help.Message))
{
return Help.Message;
}
else
{
return HelpMessage;
}
}
}
[JsonProperty("environment")]
public EssentialsEnvironmentPropertiesConfig Environment { get; set; }
@@ -208,21 +182,9 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("volumes")]
public EssentialsRoomVolumesConfig Volumes { get; set; }
[JsonProperty("fusion")]
public EssentialsRoomFusionConfig Fusion { get; set; }
[JsonProperty("essentialsRoomUiBehaviorConfig", NullValueHandling=NullValueHandling.Ignore)]
public EssentialsRoomUiBehaviorConfig UiBehavior { get; set; }
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
/// <summary>
/// Indicates if this room represents a combination of other rooms
/// </summary>
[JsonProperty("isRoomCombinationScenario")]
public bool IsRoomCombinationScenario { get; set; }
public EssentialsRoomPropertiesConfig()
{
LogoLight = new EssentialsLogoPropertiesConfig();
@@ -230,32 +192,15 @@ namespace PepperDash.Essentials.Room.Config
}
}
public class EssentialsRoomUiBehaviorConfig
{
[JsonProperty("disableActivityButtonsWhileWarmingCooling")]
public bool DisableActivityButtonsWhileWarmingCooling { get; set; }
}
public class EssentialsAvRoomPropertiesConfig : EssentialsRoomPropertiesConfig
{
[JsonProperty("defaultAudioKey")]
public string DefaultAudioKey { get; set; }
[JsonProperty("sourceListKey")]
public string SourceListKey { get; set; }
[JsonProperty("destinationListKey")]
public string DestinationListKey { get; set; }
[JsonProperty("defaultSourceItem")]
public string DefaultSourceItem { get; set; }
/// <summary>
/// Indicates if the room supports advanced sharing
/// </summary>
[JsonProperty("supportsAdvancedSharing")]
public bool SupportsAdvancedSharing { get; set; }
/// <summary>
/// Indicates if non-tech users can change the share mode
/// </summary>
[JsonProperty("userCanChangeShareMode")]
public bool UserCanChangeShareMode { get; set; }
}
public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig
@@ -280,32 +225,6 @@ 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")]

View File

@@ -1,75 +0,0 @@
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; }
[JsonProperty("helpMessage")]
public string HelpMessage { 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>();
}
}
}

View File

@@ -17,11 +17,11 @@ namespace PepperDash.Essentials.Room
public class EssentialsRoomEmergencyContactClosure : EssentialsRoomEmergencyBase
{
IEssentialsRoom Room;
EssentialsRoomBase Room;
string Behavior;
bool TriggerOnClose;
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, IEssentialsRoom room) :
public EssentialsRoomEmergencyContactClosure(string key, EssentialsRoomEmergencyConfig config, EssentialsRoomBase room) :
base(key)
{
Room = room;

View File

@@ -1,821 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials
{
public class EssentialsCombinedHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
{
private bool _codecExternalSourceChange;
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSourceChange;
//************************
// Call-related stuff
public BoolFeedback InCallFeedback { get; private set; }
///// <summary>
///// Make this more specific
///// </summary>
//public List<CodecActiveCallItem> ActiveCalls { get; private set; }
/// <summary>
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
/// </summary>
public IntFeedback CallTypeFeedback { get; private set; }
/// <summary>
///
/// </summary>
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
/// <summary>
/// When something in the room is sharing with the far end or through other means
/// </summary>
public BoolFeedback IsSharingFeedback { get; private set; }
//************************
protected override Func<bool> OnFeedbackFunc
{
get
{
return () =>
{
var displays = Displays.OfType<DisplayBase>().ToList();
var val = CurrentSourceInfo != null
&& CurrentSourceInfo.Type == eSourceListItemType.Route
&& displays.Count > 0;
//&& disp.PowerIsOnFeedback.BoolValue;
return val;
};
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsWarmingFeedbackFunc
{
get
{
return () => Displays.OfType<TwoWayDisplayBase>().Any((d) => d.IsWarmingUpFeedback.BoolValue);
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsCoolingFeedbackFunc
{
get
{
return () => Displays.OfType<TwoWayDisplayBase>().Any((d) => d.IsCoolingDownFeedback.BoolValue);
}
}
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
private List<IRoutingSinkWithSwitching> Displays;
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
public VideoCodecBase VideoCodec { get; private set; }
public AudioCodecBase AudioCodec { get; private set; }
public bool ExcludeFromGlobalFunctions { get; set; }
public string DefaultSourceItem { get; set; }
public ushort DefaultVolume { get; set; }
/// <summary>
/// If room is off, enables power on to last source. Default true
/// </summary>
public bool EnablePowerOnToLastSource { get; set; }
string LastSourceKey;
/// <summary>
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
/// tag to device.
/// </summary>
public IBasicVolumeControls CurrentVolumeControls
{
get { return _CurrentAudioDevice; }
set
{
if (value == _CurrentAudioDevice) return;
var oldDev = _CurrentAudioDevice;
// derigister this room from the device, if it can
if (oldDev is IInUseTracking)
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
var handler = CurrentVolumeDeviceChange;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
_CurrentAudioDevice = value;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
// register this room with new device, if it can
if (_CurrentAudioDevice is IInUseTracking)
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
}
}
IBasicVolumeControls _CurrentAudioDevice;
/// <summary>
/// The SourceListItem last run - containing names and icons
/// </summary>
public SourceListItem CurrentSourceInfo
{
get { return _CurrentSourceInfo; }
set
{
if (value == _CurrentSourceInfo) return;
var handler = CurrentSourceChange;
// remove from in-use tracker, if so equipped
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
_CurrentSourceInfo = value;
// add to in-use tracking
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
var vc = VideoCodec as IHasExternalSourceSwitching;
if (vc != null && !_codecExternalSourceChange)
{
vc.SetSelectedSource(CurrentSourceInfoKey);
}
_codecExternalSourceChange = false;
}
}
SourceListItem _CurrentSourceInfo;
public string CurrentSourceInfoKey { get; set; }
/// <summary>
/// "codecOsd"
/// </summary>
public string DefaultCodecRouteString { get { return "codecOsd"; } }
/// <summary>
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
/// always returns the VideoCodec if it is capable
/// </summary>
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
CCriticalSection SourceSelectLock = new CCriticalSection();
public EssentialsCombinedHuddleVtc1Room(DeviceConfig config)
: base(config)
{
try
{
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
(config.Properties.ToString());
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
if (VideoCodec == null)
throw new ArgumentNullException("codec cannot be null");
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
if (AudioCodec == null)
Debug.Console(0, this, "No Audio Codec Found");
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
Displays = new List<IRoutingSinkWithSwitching>();
Initialize();
}
catch (Exception e)
{
Debug.Console(1, this, "Error building room: \n{0}", e);
}
}
void Initialize()
{
try
{
if (DefaultAudioDevice is IBasicVolumeControls)
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
else if (DefaultAudioDevice is IHasVolumeDevice)
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
CurrentVolumeControls = DefaultVolumeControls;
// Combines call feedback from both codecs if available
InCallFeedback = new BoolFeedback(() =>
{
bool inAudioCall = false;
bool inVideoCall = false;
if (AudioCodec != null)
inAudioCall = AudioCodec.IsInCall;
if (VideoCodec != null)
inVideoCall = VideoCodec.IsInCall;
if (inAudioCall || inVideoCall)
return true;
else
return false;
});
SetupDisplays();
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
// Get emergency object, if any
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
Debug.Console(2, this, "Emergency Config evaluated.");
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
if (AudioCodec != null)
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
// link privacy to VC (for now?)
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
CallTypeFeedback = new IntFeedback(() => 0);
SetSourceListKey();
EnablePowerOnToLastSource = true;
}
catch (Exception e)
{
Debug.Console(0, this, "Error Initializing Room: {0}", e);
}
}
private void SetupDisplays()
{
//DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
var destinationList = ConfigReader.ConfigObject.DestinationLists[PropertiesConfig.DestinationListKey];
foreach (var destination in destinationList)
{
var dest = destination.Value.SinkDevice as IRoutingSinkWithSwitching;
if (dest != null)
{
Displays.Add(dest);
}
var display = dest as DisplayBase;
if (display != null)
{
// Link power, warming, cooling to display
var dispTwoWay = display as IHasPowerControlWithFeedback;
if (dispTwoWay != null)
{
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
//if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
// CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
};
}
display.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
IsWarmingUpFeedback.FireUpdate();
if (!IsWarmingUpFeedback.BoolValue)
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
};
display.IsCoolingDownFeedback.OutputChange += (o, a) =>
{
IsCoolingDownFeedback.FireUpdate();
};
}
}
}
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
{
SetSourceListKey(PropertiesConfig.SourceListKey);
}
else
{
SetSourceListKey(Key);
}
SetCodecExternalSources();
}
protected override void CustomSetConfig(DeviceConfig config)
{
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
if (newPropertiesConfig != null)
PropertiesConfig = newPropertiesConfig;
ConfigWriter.UpdateRoomConfig(config);
}
public override bool CustomActivate()
{
// Add Occupancy object from config
if (PropertiesConfig.Occupancy != null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
}
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
return base.CustomActivate();
}
/// <summary>
///
/// </summary>
protected override void EndShutdown()
{
VideoCodec.EndAllCalls();
SetDefaultLevels();
RunDefaultPresentRoute();
CrestronEnvironment.Sleep(1000);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
RunRouteAction("roomOff");
VideoCodec.StopSharing();
VideoCodec.StandbyActivate();
}
/// <summary>
/// Routes the default source item, if any. Returns true when default route exists
/// </summary>
public override bool RunDefaultPresentRoute()
{
if (DefaultSourceItem != null)
RunRouteAction(DefaultSourceItem);
return DefaultSourceItem != null;
}
/// <summary>
/// Sets up the room when started into call mode without presenting a source
/// </summary>
/// <returns></returns>
public bool RunDefaultCallRoute()
{
RunRouteAction(DefaultCodecRouteString);
return true;
}
public void RunRouteActionCodec(string routeKey, string sourceListKey)
{
_codecExternalSourceChange = true;
RunRouteAction(routeKey, sourceListKey);
}
/// <summary>
///
/// </summary>
/// <param name="routeKey"></param>
public void RunRouteAction(string routeKey)
{
RunRouteAction(routeKey, new Action(() => { }));
}
/// <summary>
///
/// </summary>
/// <param name="routeKey"></param>
/// <param name="souceListKey"></param>
/// <param name="successCallback"></param>
public void RunRouteAction(string routeKey, string sourceListKey)
{
if (string.IsNullOrEmpty(sourceListKey))
{
Debug.Console(1, this, "No sourceListKey present. RunRouteAction assumes default source list.");
RunRouteAction(routeKey, new Action(() => { }));
}
else
{
Debug.Console(1, this, "sourceListKey present but not yet implemented");
throw new NotImplementedException();
}
}
/// <summary>
///
/// </summary>
/// <param name="routeKey"></param>
/// <param name="souceListKey"></param>
/// <param name="successCallback"></param>
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
{
if (string.IsNullOrEmpty(sourceListKey))
{
RunRouteAction(routeKey, successCallback);
}
else
throw new NotImplementedException();
}
/// <summary>
/// Gets a source from config list SourceListKey and dynamically build and executes the
/// route or commands
/// </summary>
/// <param name="name"></param>
public void RunRouteAction(string routeKey, Action successCallback)
{
// Run this on a separate thread
new CTimer(o =>
{
// try to prevent multiple simultaneous selections
SourceSelectLock.TryEnter();
try
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
if (dict == null)
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
return;
}
// Try to get the list item by it's string key
if (!dict.ContainsKey(routeKey))
{
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
routeKey, SourceListKey);
return;
}
// End usage timer on last source
if (!string.IsNullOrEmpty(LastSourceKey))
{
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
if (usageLastSource != null && usageLastSource.UsageTracker != null)
{
try
{
// There MAY have been failures in here. Protect
usageLastSource.UsageTracker.EndDeviceUsage();
}
catch (Exception e)
{
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
}
}
}
// Let's run it
var item = dict[routeKey];
if (routeKey.ToLower() != "roomoff")
{
LastSourceKey = routeKey;
}
else
CurrentSourceInfoKey = null;
// hand off the individual routes to this helper
foreach (var route in item.RouteList)
DoRouteItem(route);
// Start usage timer on routed source
var usageNewSource = item.SourceDevice as IUsageTracking;
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
{
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
}
// See if this can be moved into common, base-class method -------------
// Set volume control, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
volDev = DefaultVolumeControls;
//else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
// volDev = DefaultDisplay as IBasicVolumeControls;
// Or a specific device, probably rarely used.
else
{
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
if (dev is IBasicVolumeControls)
volDev = dev as IBasicVolumeControls;
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
if (volDev != CurrentVolumeControls)
{
// zero the volume on the device we are leaving.
// Set the volume to default on device we are entering
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
vd.SetVolume(0);
}
CurrentVolumeControls = volDev;
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
// -----------------------------------------------------------------------
// store the name and UI info for routes
if (item.SourceKey == "$off")
{
CurrentSourceInfoKey = routeKey;
CurrentSourceInfo = null;
}
else if (item.SourceKey != null)
{
CurrentSourceInfoKey = routeKey;
CurrentSourceInfo = item;
}
OnFeedback.FireUpdate();
if (OnFeedback.BoolValue)
{
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
{
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
VideoCodec.StandbyDeactivate();
}
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
{
VideoCodec.StandbyDeactivate();
}
else
{
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
}
}
else
{
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
}
// report back when done
if (successCallback != null)
successCallback();
}
catch (Exception e)
{
Debug.Console(1, this, "ERROR in routing: {0}", e);
}
SourceSelectLock.Leave();
}, 0); // end of CTimer
}
/// <summary>
///
/// </summary>
/// <param name="route"></param>
void DoRouteItem(SourceRouteListItem route)
{
// if there is a $defaultAll on route, run two separate
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
{
foreach (var display in Displays)
{
var tempVideo = new SourceRouteListItem
{
DestinationKey = display.Key,
SourceKey = route.SourceKey,
Type = eRoutingSignalType.Video
};
DoRoute(tempVideo);
}
}
else
DoRoute(route);
}
/// <summary>
///
/// </summary>
/// <param name="route"></param>
/// <returns></returns>
bool DoRoute(SourceRouteListItem route)
{
IRoutingSink dest = null;
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
dest = DefaultAudioDevice as IRoutingSink;
//else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
// dest = DefaultDisplay;
else
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
if (dest == null)
{
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
return false;
}
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{
dest.ReleaseRoute();
if (dest is IHasPowerControl)
(dest as IHasPowerControl).PowerOff();
}
else
{
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
if (source == null)
{
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
return false;
}
dest.ReleaseAndMakeRoute(source, route.Type);
}
return true;
}
public override void RoomVacatedForTimeoutPeriod(object o)
{
//Implement this
}
/// <summary>
/// Does what it says
/// </summary>
public override void SetDefaultLevels()
{
Debug.Console(1, this, "Restoring default levels");
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
if (vc != null)
vc.SetVolume(DefaultVolume);
}
/// <summary>
/// Will power the room on with the last-used source
/// </summary>
public override void PowerOnToDefaultOrLastSource()
{
if (!EnablePowerOnToLastSource || LastSourceKey == null)
return;
RunRouteAction(LastSourceKey);
}
/// <summary>
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
/// </summary>
public static void AllRoomsOff()
{
var allRooms = DeviceManager.AllDevices.Where(d =>
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
foreach (var room in allRooms)
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
}
/// <summary>
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
/// </summary>
private void SetCodecExternalSources()
{
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
{
return;
}
try
{
// Get the tie line that the external switcher is connected to
string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
videoCodecWithExternalSwitching.ClearExternalSources();
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
{
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
}
}
}
catch (Exception e)
{
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
}
}
private void SetCodecBranding()
{
var vcWithBranding = VideoCodec as IHasBranding;
if (vcWithBranding == null) return;
Debug.Console(1, this, "Setting Codec Branding");
vcWithBranding.InitializeBranding(Key);
}
#region IPrivacy Members
public void PrivacyModeOff()
{
VideoCodec.PrivacyModeOff();
}
public void PrivacyModeOn()
{
VideoCodec.PrivacyModeOn();
}
public void PrivacyModeToggle()
{
VideoCodec.PrivacyModeToggle();
}
#endregion
}
}

View File

@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
@@ -77,9 +74,8 @@ namespace PepperDash.Essentials
var leftDisp = LeftDisplay as DisplayBase;
var rightDisp = RightDisplay as DisplayBase;
if (leftDisp != null && RightDisplay != null)
return leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue;
else
return false;
return rightDisp != null && (leftDisp.IsWarmingUpFeedback.BoolValue || rightDisp.IsWarmingUpFeedback.BoolValue);
return false;
};
}
}
@@ -96,9 +92,8 @@ namespace PepperDash.Essentials
var leftDisp = LeftDisplay as DisplayBase;
var rightDisp = RightDisplay as DisplayBase;
if (leftDisp != null && RightDisplay != null)
return leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue;
else
return false;
return rightDisp != null && (leftDisp.IsCoolingDownFeedback.BoolValue || rightDisp.IsCoolingDownFeedback.BoolValue);
return false;
};
}
}
@@ -120,7 +115,7 @@ namespace PepperDash.Essentials
/// If room is off, enables power on to last source. Default true
/// </summary>
public bool EnablePowerOnToLastSource { get; set; }
string LastSourceKey;
string _lastSourceKey;
/// <summary>
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
@@ -128,27 +123,27 @@ namespace PepperDash.Essentials
/// </summary>
public IBasicVolumeControls CurrentVolumeControls
{
get { return _CurrentAudioDevice; }
get { return _currentAudioDevice; }
set
{
if (value == _CurrentAudioDevice) return;
if (value == _currentAudioDevice) return;
var oldDev = _CurrentAudioDevice;
var oldDev = _currentAudioDevice;
// derigister this room from the device, if it can
if (oldDev is IInUseTracking)
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
var handler = CurrentVolumeDeviceChange;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
_CurrentAudioDevice = value;
_currentAudioDevice = value;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
// register this room with new device, if it can
if (_CurrentAudioDevice is IInUseTracking)
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
if (_currentAudioDevice is IInUseTracking)
(_currentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
}
}
IBasicVolumeControls _CurrentAudioDevice;
IBasicVolumeControls _currentAudioDevice;
/// <summary>
/// "codecOsd"
@@ -161,7 +156,7 @@ namespace PepperDash.Essentials
/// </summary>
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
CCriticalSection SourceSelectLock = new CCriticalSection();
readonly CCriticalSection _sourceSelectLock = new CCriticalSection();
public EssentialsDualDisplayRoom(DeviceConfig config)
: base(config)
@@ -196,18 +191,18 @@ namespace PepperDash.Essentials
}
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
VideoCodecBase;
if (VideoCodec == null)
throw new ArgumentNullException("codec cannot be null");
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
AudioCodecBase;
if (AudioCodec == null)
Debug.Console(0, this, "No Audio Codec Found");
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
InitializeRoom();
Initialize();
}
catch (Exception e)
{
@@ -215,10 +210,10 @@ namespace PepperDash.Essentials
}
}
void InitializeRoom()
void Initialize()
{
if (DefaultAudioDevice is IBasicVolumeControls)
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
if (DefaultAudioDevice != null)
DefaultVolumeControls = DefaultAudioDevice;
else if (DefaultAudioDevice is IHasVolumeDevice)
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
CurrentVolumeControls = DefaultVolumeControls;
@@ -233,12 +228,12 @@ namespace PepperDash.Essentials
InitializeDisplay(rightDisp);
// Get Microphone Privacy object, if any
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
// Get emergency object, if any
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
Debug.Console(2, this, "Emergency Config evaluated.");
@@ -254,43 +249,27 @@ namespace PepperDash.Essentials
if (VideoCodec != null)
inVideoCall = VideoCodec.IsInCall;
if (inAudioCall || inVideoCall)
return true;
else
return false;
return inAudioCall || inVideoCall;
});
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
VideoCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
if (AudioCodec != null)
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
// link privacy to VC (for now?)
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
CallTypeFeedback = new IntFeedback(() => 0);
SetSourceListKey();
SourceListKey = "default";
EnablePowerOnToLastSource = true;
}
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
{
SetSourceListKey(PropertiesConfig.SourceListKey);
}
else
{
SetSourceListKey(Key);
}
}
void InitializeDisplay(DisplayBase disp)
{
if (disp != null)
@@ -317,13 +296,18 @@ namespace PepperDash.Essentials
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
IsWarmingUpFeedback.FireUpdate();
if (!IsWarmingUpFeedback.BoolValue)
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
};
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
{
IsCoolingDownFeedback.FireUpdate();
if (IsWarmingUpFeedback.BoolValue)
{
return;
}
var basicVolumeWithFeedback = CurrentVolumeControls as IBasicVolumeWithFeedback;
if (basicVolumeWithFeedback != null)
{
basicVolumeWithFeedback.SetVolume(DefaultVolume);
}
};
disp.IsCoolingDownFeedback.OutputChange += (o, a) => IsCoolingDownFeedback.FireUpdate();
}
}
@@ -341,11 +325,12 @@ namespace PepperDash.Essentials
{
// Add Occupancy object from config
if (PropertiesConfig.Occupancy != null)
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
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);
@@ -393,6 +378,7 @@ namespace PepperDash.Essentials
///
/// </summary>
/// <param name="routeKey"></param>
/// <param name="sourceListKey"></param>
public void RunRouteAction(string routeKey, string sourceListKey)
{
RunRouteAction(routeKey, sourceListKey, null);
@@ -402,14 +388,17 @@ namespace PepperDash.Essentials
/// Gets a source from config list SourceListKey and dynamically build and executes the
/// route or commands
/// </summary>
/// <param name="name"></param>
/// <param name="routeKey"></param>
/// <param name="sourceListKey"></param>
/// <param name="successCallback"></param>
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
{
// Run this on a separate thread
new CTimer(o =>
//new CTimer
CrestronInvoke.BeginInvoke(o =>
{
// try to prevent multiple simultaneous selections
SourceSelectLock.TryEnter();
_sourceSelectLock.TryEnter();
try
{
@@ -431,9 +420,9 @@ namespace PepperDash.Essentials
}
// End usage timer on last source
if (!string.IsNullOrEmpty(LastSourceKey))
if (!string.IsNullOrEmpty(_lastSourceKey))
{
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
var usageLastSource = dict[_lastSourceKey].SourceDevice as IUsageTracking;
if (usageLastSource != null && usageLastSource.UsageTracker != null)
{
try
@@ -453,7 +442,7 @@ namespace PepperDash.Essentials
if (routeKey.ToLower() != "roomoff")
{
LastSourceKey = routeKey;
_lastSourceKey = routeKey;
}
//else
// CurrentSourceInfoKey = null;
@@ -538,7 +527,7 @@ namespace PepperDash.Essentials
Debug.Console(1, this, "ERROR in routing: {0}", e);
}
SourceSelectLock.Leave();
_sourceSelectLock.Leave();
}, 0); // end of CTimer
}
@@ -547,6 +536,8 @@ namespace PepperDash.Essentials
///
/// </summary>
/// <param name="route"></param>
/// <param name="sourceItem"></param>
/// <param name="sourceItemKey"></param>
void DoRouteItem(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
{
// if there is a $defaultAll on route, run two separate
@@ -570,7 +561,7 @@ namespace PepperDash.Essentials
/// </summary>
/// <param name="route"></param>
/// <returns></returns>
bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
private bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
{
IRoutingSink dest = null;
@@ -634,9 +625,9 @@ namespace PepperDash.Essentials
/// </summary>
public override void PowerOnToDefaultOrLastSource()
{
if (!EnablePowerOnToLastSource || LastSourceKey == null)
if (!EnablePowerOnToLastSource || _lastSourceKey == null)
return;
RunRouteAction(LastSourceKey, SourceListKey);
RunRouteAction(_lastSourceKey, SourceListKey);
}
/// <summary>
@@ -644,10 +635,11 @@ namespace PepperDash.Essentials
/// </summary>
public static void AllRoomsOff()
{
var allRooms = DeviceManager.AllDevices.Where(d =>
d is IEssentialsHuddleSpaceRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
var allRooms = DeviceManager.AllDevices.OfType<EssentialsHuddleSpaceRoom>().Where(d => !d.ExcludeFromGlobalFunctions);
foreach (var room in allRooms)
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff", (room as IEssentialsHuddleSpaceRoom).SourceListKey);
{
room.RunRouteAction("roomOff", room.SourceListKey);
}
}
#region IPrivacy Members

View File

@@ -1,11 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
@@ -13,150 +7,23 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IEssentialsHuddleSpaceRoom
{
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSourceChange;
protected override Func<bool> OnFeedbackFunc
{
get
{
return () =>
{
var disp = DefaultDisplay as DisplayBase;
var val = CurrentSourceInfo != null
&& CurrentSourceInfo.Type == eSourceListItemType.Route
&& disp != null;
//&& disp.PowerIsOnFeedback.BoolValue;
return val;
};
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsWarmingFeedbackFunc
{
get
{
return () =>
{
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
return disp.IsWarmingUpFeedback.BoolValue;
else
return false;
};
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsCoolingFeedbackFunc
{
get
{
return () =>
{
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
return disp.IsCoolingDownFeedback.BoolValue;
else
return false;
};
}
}
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
public IRoutingSink DefaultAudioDevice { get; private set; }
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
public bool ExcludeFromGlobalFunctions { get; set; }
public string DefaultSourceItem { get; set; }
public ushort DefaultVolume { get; set; }
/// <summary>
/// If room is off, enables power on to last source. Default true
/// </summary>
public bool EnablePowerOnToLastSource { get; set; }
string LastSourceKey;
/// <summary>
///
/// </summary>
public IBasicVolumeControls CurrentVolumeControls
{
get { return _CurrentAudioDevice; }
set
{
if (value == _CurrentAudioDevice) return;
var oldDev = _CurrentAudioDevice;
// derigister this room from the device, if it can
if (oldDev is IInUseTracking)
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
var handler = CurrentVolumeDeviceChange;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
_CurrentAudioDevice = value;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
// register this room with new device, if it can
if (_CurrentAudioDevice is IInUseTracking)
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
}
}
IBasicVolumeControls _CurrentAudioDevice;
/// <summary>
/// The SourceListItem last run - containing names and icons
/// </summary>
public SourceListItem CurrentSourceInfo
{
get { return _CurrentSourceInfo; }
set
{
if (value == _CurrentSourceInfo) return;
var handler = CurrentSourceChange;
// remove from in-use tracker, if so equipped
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
_CurrentSourceInfo = value;
// add to in-use tracking
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null)
handler( _CurrentSourceInfo, ChangeType.DidChange);
}
}
SourceListItem _CurrentSourceInfo;
public string CurrentSourceInfoKey { get; set; }
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IRunRouteAction,
IRunDefaultPresentRoute, IHasCurrentVolumeControls, IHasDefaultDisplay, IHasCurrentSourceInfoChange
{
public EssentialsHuddleSpaceRoom(DeviceConfig config)
: base(config)
{
try
{
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>
(config.Properties.ToString());
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
PropertiesConfig = config.Properties.ToObject<EssentialsHuddleRoomPropertiesConfig>();
DefaultDisplay =
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
//why are we assuming IRoutingSinkWithSwitching here?
DefaultAudioDevice =
DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IRoutingSinkWithSwitching;
InitializeRoom();
Initialize();
}
catch (Exception e)
{
@@ -164,16 +31,57 @@ namespace PepperDash.Essentials
}
}
void InitializeRoom()
{
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
private void Initialize()
{
if (DefaultAudioDevice is IBasicVolumeControls)
{
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
}
else if (DefaultAudioDevice is IHasVolumeDevice)
{
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
}
CurrentVolumeControls = DefaultVolumeControls;
SourceListKey = String.IsNullOrEmpty(PropertiesConfig.SourceListKey)
? "default"
: PropertiesConfig.SourceListKey;
EnablePowerOnToLastSource = true;
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
if (disp == null)
{
return;
}
IsWarmingFeedbackFunc = () => disp.IsWarmingUpFeedback.BoolValue;
IsCoolingFeedbackFunc = () => disp.IsCoolingDownFeedback.BoolValue;
OnFeedbackFunc = () => CurrentSourceInfo != null
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
InitializeDisplay(disp);
}
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
IsCoolingDownFeedback.FireUpdate();
}
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
var display = sender as DisplayBase;
if (display == null)
{
return;
}
if (display.PowerIsOnFeedback.BoolValue == OnFeedback.BoolValue)
{
// Link power, warming, cooling to display
var dispTwoWay = disp as IHasPowerControlWithFeedback;
@@ -189,376 +97,70 @@ namespace PepperDash.Essentials
}
};
}
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
IsWarmingUpFeedback.FireUpdate();
if (!IsWarmingUpFeedback.BoolValue)
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
};
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
{
IsCoolingDownFeedback.FireUpdate();
};
}
SetupEnvironmentalControlDevices();
SetSourceListKey();
EnablePowerOnToLastSource = true;
}
private void SetupEnvironmentalControlDevices()
{
if (PropertiesConfig.Environment != null)
if (!display.PowerIsOnFeedback.BoolValue)
{
if (PropertiesConfig.Environment.Enabled)
{
foreach (var d in PropertiesConfig.Environment.DeviceKeys)
{
var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
EnvironmentalControlDevices.Add(envDevice);
}
}
CurrentSourceInfo = null;
}
OnFeedback.FireUpdate();
}
private void SetSourceListKey()
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs feedbackEventArgs)
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
IsWarmingUpFeedback.FireUpdate();
if (IsWarmingUpFeedback.BoolValue)
{
SetSourceListKey(PropertiesConfig.SourceListKey);
}
else
{
SetSourceListKey(Key);
return;
}
var displayVolumeControl = DefaultDisplay as IBasicVolumeWithFeedback;
if (displayVolumeControl == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
"Default display {0} is not volume control control provider", DefaultDisplay.Key);
return;
}
displayVolumeControl.SetVolume(DefaultVolume);
}
protected override void CustomSetConfig(DeviceConfig config)
{
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
var newPropertiesConfig =
JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
if (newPropertiesConfig != null)
PropertiesConfig = newPropertiesConfig;
ConfigWriter.UpdateRoomConfig(config);
}
/// <summary>
///
/// </summary>
protected override void EndShutdown()
{
SetDefaultLevels();
RunDefaultPresentRoute();
CrestronEnvironment.Sleep(1000);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
RunRouteAction("roomOff");
}
/// <summary>
/// Routes the default source item, if any
/// </summary>
public override bool RunDefaultPresentRoute()
{
if (DefaultSourceItem == null)
{
Debug.Console(0, this, "Unable to run default present route, DefaultSourceItem is null.");
return false;
PropertiesConfig = newPropertiesConfig;
}
RunRouteAction(DefaultSourceItem);
return true;
ConfigWriter.UpdateRoomConfig(config);
}
public override bool CustomActivate()
{
// Add Occupancy object from config
if (PropertiesConfig.Occupancy != null)
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
{
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
}
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>
/// <param name="routeKey"></param>
public void RunRouteAction(string routeKey)
{
RunRouteAction(routeKey, new Action(() => { }));
}
/// <summary>
///
/// </summary>
/// <param name="routeKey"></param>
/// <param name="souceListKey"></param>
/// <param name="successCallback"></param>
public void RunRouteAction(string routeKey, string sourceListKey)
{
RunRouteAction(routeKey, new Action(() => { }));
}
/// <summary>
///
/// </summary>
/// <param name="routeKey"></param>
/// <param name="souceListKey"></param>
/// <param name="successCallback"></param>
public void RunRouteAction(string routeKey, string sourceListKey, Action successCallback)
{
if (string.IsNullOrEmpty(sourceListKey))
{
RunRouteAction(routeKey, successCallback);
}
else
throw new NotImplementedException();
}
/// <summary>
/// Gets a source from config list SourceListKey and dynamically build and executes the
/// route or commands
/// </summary>
/// <param name="name"></param>
public void RunRouteAction(string routeKey, Action successCallback)
{
// Run this on a separate thread
new CTimer(o =>
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Run route action '{0}'", routeKey);
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
if(dict == null)
{
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
return;
}
// Try to get the list item by it's string key
if (!dict.ContainsKey(routeKey))
{
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
routeKey, SourceListKey);
return;
}
var item = dict[routeKey];
//Debug.Console(2, this, "Action {0} has {1} steps",
// item.SourceKey, item.RouteList.Count);
// End usage timer on last source
if (!string.IsNullOrEmpty(LastSourceKey))
{
var lastSource = dict[LastSourceKey].SourceDevice;
try
{
if (lastSource != null && lastSource is IUsageTracking)
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
}
catch (Exception e)
{
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
}
}
// Let's run it
if (routeKey.ToLower() != "roomoff")
{
LastSourceKey = routeKey;
}
else
{
CurrentSourceInfoKey = null;
}
foreach (var route in item.RouteList)
{
// if there is a $defaultAll on route, run two separate
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
{
// Going to assume a single-path route for now
var tempVideo = new SourceRouteListItem
{
DestinationKey = "$defaultDisplay",
SourceKey = route.SourceKey,
Type = eRoutingSignalType.Video
};
DoRoute(tempVideo);
//var tempAudio = new SourceRouteListItem
//{
// DestinationKey = "$defaultAudio",
// SourceKey = route.SourceKey,
// Type = eRoutingSignalType.Audio
//};
//DoRoute(tempAudio);
//continue; -- not sure why this was here
}
else
DoRoute(route);
}
// Start usage timer on routed source
if (item.SourceDevice is IUsageTracking)
{
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
}
// Set volume control, using default if non provided
IBasicVolumeControls volDev = null;
// Handle special cases for volume control
if (string.IsNullOrEmpty(item.VolumeControlKey)
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
volDev = DefaultVolumeControls;
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
volDev = DefaultDisplay as IBasicVolumeControls;
// Or a specific device, probably rarely used.
else
{
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
if (dev is IBasicVolumeControls)
volDev = dev as IBasicVolumeControls;
else if (dev is IHasVolumeDevice)
volDev = (dev as IHasVolumeDevice).VolumeDevice;
}
if (volDev != CurrentVolumeControls)
{
// zero the volume on the device we are leaving.
// Set the volume to default on device we are entering
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
SavedVolumeLevels[vd] = (uint)vd.VolumeLevelFeedback.IntValue;
vd.SetVolume(0);
}
CurrentVolumeControls = volDev;
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
// store the name and UI info for routes
if (item.SourceKey == "$off")
{
CurrentSourceInfoKey = routeKey;
CurrentSourceInfo = null;
}
else if (item.SourceKey != null)
{
CurrentSourceInfoKey = routeKey;
CurrentSourceInfo = item;
}
// And finally, set the "control". This will trigger event
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
OnFeedback.FireUpdate();
// report back when done
if (successCallback != null)
successCallback();
}, 0); // end of CTimer
}
/// <summary>
/// Will power the room on with the last-used source
/// </summary>
public override void PowerOnToDefaultOrLastSource()
{
if (!EnablePowerOnToLastSource || LastSourceKey == null)
return;
RunRouteAction(LastSourceKey);
}
/// <summary>
/// Does what it says
/// </summary>
public override void SetDefaultLevels()
{
Debug.Console(1, this, "Restoring default levels");
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
if (vc != null)
vc.SetVolume(DefaultVolume);
}
/// <summary>
///
/// </summary>
/// <param name="route"></param>
/// <returns></returns>
bool DoRoute(SourceRouteListItem route)
{
IRoutingSink dest = null;
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
dest = DefaultAudioDevice;
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
dest = DefaultDisplay;
else
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
if (dest == null)
{
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
return false;
}
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{
dest.ReleaseRoute();
if (dest is IHasPowerControl)
(dest as IHasPowerControl).PowerOff();
}
else
{
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
if (source == null)
{
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
return false;
}
dest.ReleaseAndMakeRoute(source, route.Type);
}
return true;
}
public override void RoomVacatedForTimeoutPeriod(object o)
{
//Implement this
//TODO: Implement RoomVacatedForTimeoutPeriod
}
/// <summary>
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
/// </summary>
public static void AllRoomsOff()
{
var allRooms = DeviceManager.AllDevices.Where(d =>
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
foreach (var room in allRooms)
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
}
}
}
}

View File

@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
@@ -17,9 +15,9 @@ using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials
{
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
{
private bool _codecExternalSourceChange;
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange,
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
{
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSourceChange;
@@ -50,57 +48,7 @@ namespace PepperDash.Essentials
public BoolFeedback IsSharingFeedback { get; private set; }
//************************
protected override Func<bool> OnFeedbackFunc
{
get
{
return () =>
{
var disp = DefaultDisplay as DisplayBase;
var val = CurrentSourceInfo != null
&& CurrentSourceInfo.Type == eSourceListItemType.Route
&& disp != null;
//&& disp.PowerIsOnFeedback.BoolValue;
return val;
};
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsWarmingFeedbackFunc
{
get
{
return () =>
{
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
return disp.IsWarmingUpFeedback.BoolValue;
else
return false;
};
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsCoolingFeedbackFunc
{
get
{
return () =>
{
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
return disp.IsCoolingDownFeedback.BoolValue;
else
return false;
};
}
}
public EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; private set; }
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
@@ -121,72 +69,42 @@ namespace PepperDash.Essentials
/// If room is off, enables power on to last source. Default true
/// </summary>
public bool EnablePowerOnToLastSource { get; set; }
string LastSourceKey;
/// <summary>
/// Sets the volume control device, and attaches/removes InUseTrackers with "audio"
/// tag to device.
/// </summary>
public IBasicVolumeControls CurrentVolumeControls
{
get { return _CurrentAudioDevice; }
set
{
if (value == _CurrentAudioDevice) return;
var oldDev = _CurrentAudioDevice;
// derigister this room from the device, if it can
if (oldDev is IInUseTracking)
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
var handler = CurrentVolumeDeviceChange;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
_CurrentAudioDevice = value;
if (handler != null)
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
// register this room with new device, if it can
if (_CurrentAudioDevice is IInUseTracking)
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
}
}
IBasicVolumeControls _CurrentAudioDevice;
private string _lastSourceKey;
/// <summary>
/// The SourceListItem last run - containing names and icons
/// </summary>
public SourceListItem CurrentSourceInfo
{
get { return _CurrentSourceInfo; }
get { return _currentSourceInfo; }
set
{
if (value == _CurrentSourceInfo) return;
if (value == _currentSourceInfo) return;
var handler = CurrentSourceChange;
// remove from in-use tracker, if so equipped
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
if(_currentSourceInfo != null && _currentSourceInfo.SourceDevice is IInUseTracking)
(_currentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
handler(_currentSourceInfo, ChangeType.WillChange);
_CurrentSourceInfo = value;
_currentSourceInfo = value;
// add to in-use tracking
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (_currentSourceInfo != null && _currentSourceInfo.SourceDevice is IInUseTracking)
(_currentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
var vc = VideoCodec as IHasExternalSourceSwitching;
if (vc != null && !_codecExternalSourceChange)
if (vc != null)
{
vc.SetSelectedSource(CurrentSourceInfoKey);
}
_codecExternalSourceChange = false;
}
}
SourceListItem _CurrentSourceInfo;
private SourceListItem _currentSourceInfo;
public string CurrentSourceInfoKey { get; set; }
@@ -201,7 +119,7 @@ namespace PepperDash.Essentials
/// </summary>
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
CCriticalSection SourceSelectLock = new CCriticalSection();
private readonly CCriticalSection _sourceSelectLock = new CCriticalSection();
public EssentialsHuddleVtc1Room(DeviceConfig config)
: base(config)
@@ -210,31 +128,23 @@ namespace PepperDash.Essentials
{
PropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>
(config.Properties.ToString());
DefaultDisplay = DeviceManager.GetDeviceForKey((PropertiesConfig as EssentialsHuddleVtc1PropertiesConfig).DefaultDisplayKey) as IRoutingSinkWithSwitching;
DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
if (VideoCodec == null)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "No Video Codec set. Please check 'videoCodecKey' property in room config");
throw new ArgumentNullException("VideoCodec cannot be null");
}
throw new ArgumentNullException("codec cannot be null");
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
AudioCodecBase;
if (AudioCodec == null)
Debug.Console(0, this, "No Audio Codec Found");
DefaultAudioDevice = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultAudioKey) as IBasicVolumeControls;
if (DefaultAudioDevice == null)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "No Default Audio Device set. Please check 'defaultAudioKey' property in room config");
throw new ArgumentNullException("DefaultAudioDevice cannot be null");
}
InitializeRoom();
Initialize();
}
catch (Exception e)
{
@@ -242,12 +152,12 @@ namespace PepperDash.Essentials
}
}
void InitializeRoom()
void Initialize()
{
try
{
if (DefaultAudioDevice is IBasicVolumeControls)
DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
if (DefaultAudioDevice != null)
DefaultVolumeControls = DefaultAudioDevice;
else if (DefaultAudioDevice is IHasVolumeDevice)
DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
CurrentVolumeControls = DefaultVolumeControls;
@@ -256,8 +166,8 @@ namespace PepperDash.Essentials
// Combines call feedback from both codecs if available
InCallFeedback = new BoolFeedback(() =>
{
bool inAudioCall = false;
bool inVideoCall = false;
var inAudioCall = false;
var inVideoCall = false;
if (AudioCodec != null)
inAudioCall = AudioCodec.IsInCall;
@@ -265,56 +175,16 @@ namespace PepperDash.Essentials
if (VideoCodec != null)
inVideoCall = VideoCodec.IsInCall;
if (inAudioCall || inVideoCall)
return true;
else
return false;
return inAudioCall || inVideoCall;
});
var disp = DefaultDisplay as DisplayBase;
if (disp != null)
{
// Link power, warming, cooling to display
var dispTwoWay = disp as IHasPowerControlWithFeedback;
if (dispTwoWay != null)
{
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
};
}
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
IsWarmingUpFeedback.FireUpdate();
if (!IsWarmingUpFeedback.BoolValue)
(CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
};
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
{
IsCoolingDownFeedback.FireUpdate();
};
}
// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
Debug.Console(2, this, "Microphone Privacy Config evaluated.");
// Get emergency object, if any
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
Debug.Console(2, this, "Emergency Config evaluated.");
@@ -323,22 +193,31 @@ namespace PepperDash.Essentials
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
if (AudioCodec != null)
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
AudioCodec.CallStatusChange += (o, a) => InCallFeedback.FireUpdate();
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => IsSharingFeedback.FireUpdate();
// link privacy to VC (for now?)
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => PrivacyModeIsOnFeedback.FireUpdate();
CallTypeFeedback = new IntFeedback(() => 0);
SetupEnvironmentalControlDevices();
SetSourceListKey();
SourceListKey = "default";
EnablePowerOnToLastSource = true;
var disp = DefaultDisplay as DisplayBase;
if (disp == null)
{
return;
}
OnFeedbackFunc = () => CurrentSourceInfo != null
&& CurrentSourceInfo.Type == eSourceListItemType.Route;
InitializeDisplay(disp);
}
catch (Exception e)
{
@@ -346,35 +225,49 @@ namespace PepperDash.Essentials
}
}
private void SetupEnvironmentalControlDevices()
#region Overrides of EssentialsRoomBase
protected override void PowerIsOnFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
{
if (PropertiesConfig.Environment != null)
var disp = sender as DisplayBase;
if (disp == null) return;
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (PropertiesConfig.Environment.Enabled)
{
foreach (var d in PropertiesConfig.Environment.DeviceKeys)
{
var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
EnvironmentalControlDevices.Add(envDevice);
}
}
if (!disp.PowerIsOnFeedback.BoolValue)
CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (disp.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
}
protected override void IsCoolingDownFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
{
IsCoolingDownFeedback.FireUpdate();
}
protected override void IsWarmingUpFeedbackOnOutputChange(object sender, FeedbackEventArgs args)
{
IsWarmingUpFeedback.FireUpdate();
if (IsWarmingUpFeedback.BoolValue)
{
return;
}
var basicVolumeWithFeedback = CurrentVolumeControls as IBasicVolumeWithFeedback;
if (basicVolumeWithFeedback != null)
{
basicVolumeWithFeedback.SetVolume(DefaultVolume);
}
}
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
{
SetSourceListKey(PropertiesConfig.SourceListKey);
}
else
{
SetSourceListKey(Key);
}
SetCodecExternalSources();
}
#endregion
protected override void CustomSetConfig(DeviceConfig config)
{
@@ -392,21 +285,20 @@ namespace PepperDash.Essentials
if (PropertiesConfig.Occupancy != null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
}
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>
@@ -444,31 +336,17 @@ namespace PepperDash.Essentials
/// <returns></returns>
public bool RunDefaultCallRoute()
{
Debug.Console(2, this, "RunDefaultCallRoute() Currently Sharing Content: {0}", VideoCodec.SharingContentIsOnFeedback.BoolValue);
if (VideoCodec.SharingContentIsOnFeedback.BoolValue)
{
Debug.Console(2, this, "Currently sharing content. Ignoring request to run default call route.");
return false;
}
RunRouteAction(DefaultCodecRouteString);
return true;
}
public void RunRouteActionCodec(string routeKey, string sourceListKey)
{
_codecExternalSourceChange = true;
RunRouteAction(routeKey, sourceListKey);
}
/// <summary>
///
/// </summary>
/// <param name="routeKey"></param>
public void RunRouteAction(string routeKey)
public override void RunRouteAction(string routeKey)
{
RunRouteAction(routeKey, new Action(() => { }));
RunRouteAction(routeKey, () => { });
}
/// <summary>
@@ -476,8 +354,7 @@ namespace PepperDash.Essentials
/// </summary>
/// <param name="routeKey"></param>
/// <param name="souceListKey"></param>
/// <param name="successCallback"></param>
public void RunRouteAction(string routeKey, string sourceListKey)
public void RunRouteAction(string routeKey, string souceListKey)
{
if (string.IsNullOrEmpty(sourceListKey))
{
@@ -487,8 +364,7 @@ namespace PepperDash.Essentials
else
{
Debug.Console(1, this, "sourceListKey present but not yet implemented");
RunRouteAction(routeKey, new Action(() => { }));
throw new NotImplementedException();
}
}
@@ -505,25 +381,21 @@ namespace PepperDash.Essentials
RunRouteAction(routeKey, successCallback);
}
else
{
Debug.Console(1, this, "sourceListKey present but not yet implemented");
RunRouteAction(routeKey, successCallback);
}
throw new NotImplementedException();
}
/// <summary>
/// Gets a source from config list SourceListKey and dynamically build and executes the
/// route or commands
/// </summary>
/// <param name="name"></param>
/// <summary>
/// Gets a source from config list SourceListKey and dynamically build and executes the
/// route or commands
/// </summary>
public void RunRouteAction(string routeKey, Action successCallback)
{
// Run this on a separate thread
new CTimer(o =>
//new CTimer
CrestronInvoke.BeginInvoke(o =>
{
// try to prevent multiple simultaneous selections
SourceSelectLock.TryEnter();
_sourceSelectLock.TryEnter();
try
{
@@ -545,9 +417,9 @@ namespace PepperDash.Essentials
}
// End usage timer on last source
if (!string.IsNullOrEmpty(LastSourceKey))
if (!string.IsNullOrEmpty(_lastSourceKey))
{
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
var usageLastSource = dict[_lastSourceKey].SourceDevice as IUsageTracking;
if (usageLastSource != null && usageLastSource.UsageTracker != null)
{
try
@@ -567,7 +439,7 @@ namespace PepperDash.Essentials
if (routeKey.ToLower() != "roomoff")
{
LastSourceKey = routeKey;
_lastSourceKey = routeKey;
}
else
CurrentSourceInfoKey = null;
@@ -619,7 +491,7 @@ namespace PepperDash.Essentials
if (ZeroVolumeWhenSwtichingVolumeDevices && CurrentVolumeControls is IBasicVolumeWithFeedback)
{
var vd = CurrentVolumeControls as IBasicVolumeWithFeedback;
ushort vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
var vol = (SavedVolumeLevels.ContainsKey(vd) ? (ushort)SavedVolumeLevels[vd] : DefaultVolume);
vd.SetVolume(vol);
}
}
@@ -646,21 +518,12 @@ namespace PepperDash.Essentials
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
@@ -672,7 +535,7 @@ namespace PepperDash.Essentials
Debug.Console(1, this, "ERROR in routing: {0}", e);
}
SourceSelectLock.Leave();
_sourceSelectLock.Leave();
}, 0); // end of CTimer
}
@@ -703,17 +566,16 @@ namespace PepperDash.Essentials
/// </summary>
/// <param name="route"></param>
/// <returns></returns>
bool DoRoute(SourceRouteListItem route)
private bool DoRoute(SourceRouteListItem route)
{
IRoutingSink dest = null;
IRoutingSink dest;
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
dest = DefaultAudioDevice as IRoutingSink;
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
dest = DefaultDisplay;
else
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
if (dest == null)
{
@@ -745,28 +607,6 @@ namespace PepperDash.Essentials
{
//Implement this
}
protected override bool AllowVacancyTimerToStart()
{
bool allowVideo = true;
bool allowAudio = true;
if (VideoCodec != null)
{
Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in a video call", Key, VideoCodec.IsInCall ? "is" : "is not");
allowVideo = !VideoCodec.IsInCall;
}
if (AudioCodec != null)
{
Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in an audio call", Key, AudioCodec.IsInCall ? "is" : "is not");
allowAudio = !AudioCodec.IsInCall;
}
Debug.Console(2, this, "Room {0} allowing vacancy timer to start: {1}", Key, allowVideo && allowAudio);
return allowVideo && allowAudio;
}
/// <summary>
/// Does what it says
@@ -783,9 +623,9 @@ namespace PepperDash.Essentials
/// </summary>
public override void PowerOnToDefaultOrLastSource()
{
if (!EnablePowerOnToLastSource || LastSourceKey == null)
if (!EnablePowerOnToLastSource || _lastSourceKey == null)
return;
RunRouteAction(LastSourceKey);
RunRouteAction(_lastSourceKey);
}
/// <summary>
@@ -793,10 +633,16 @@ namespace PepperDash.Essentials
/// </summary>
public static void AllRoomsOff()
{
var allRooms = DeviceManager.AllDevices.Where(d =>
d is IEssentialsRoom && !(d as IEssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
var allRooms = DeviceManager.AllDevices.Where(d =>
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
foreach (var room in allRooms)
(room as IEssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
{
var essentialsHuddleSpaceRoom = room as EssentialsHuddleSpaceRoom;
if (essentialsHuddleSpaceRoom != null)
{
essentialsHuddleSpaceRoom.RunRouteAction("roomOff");
}
}
}
@@ -819,7 +665,7 @@ namespace PepperDash.Essentials
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
videoCodecWithExternalSwitching.ClearExternalSources();
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
foreach (var kvp in srcList)

View File

@@ -1,16 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core;
using System.Collections.Generic;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
@@ -23,7 +13,7 @@ namespace PepperDash.Essentials
public Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching> Displays { get; protected set;}
public EssentialsNDisplayRoomBase(DeviceConfig config)
protected EssentialsNDisplayRoomBase(DeviceConfig config)
: base (config)
{
Displays = new Dictionary<eSourceListItemDestinationTypes, IRoutingSinkWithSwitching>();

View File

@@ -1,517 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Scheduler;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
{
public EssentialsTechRoomConfig PropertiesConfig { get; private set; }
private readonly Dictionary<string, TwoWayDisplayBase> _displays;
private readonly DevicePresetsModel _tunerPresets;
private readonly Dictionary<string, IRSetTopBoxBase> _tuners;
private Dictionary<string, string> _currentPresets;
private ScheduledEventGroup _roomScheduledEventGroup;
/// <summary>
///
/// </summary>
protected override Func<bool> IsWarmingFeedbackFunc
{
get
{
return () =>
{
return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue);
};
}
}
/// <summary>
///
/// </summary>
protected override Func<bool> IsCoolingFeedbackFunc
{
get
{
return () =>
{
return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue);
};
}
}
public EssentialsTechRoom(DeviceConfig config) : base(config)
{
PropertiesConfig = config.Properties.ToObject<EssentialsTechRoomConfig>();
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), PropertiesConfig.PresetsFileName);
_tunerPresets.SetFileName(PropertiesConfig.PresetsFileName);
_tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
_tuners = GetDevices<IRSetTopBoxBase>(PropertiesConfig.Tuners);
_displays = GetDevices<TwoWayDisplayBase>(PropertiesConfig.Displays);
RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
SetUpTunerPresetsFeedback();
SubscribeToDisplayFeedbacks();
CreateOrUpdateScheduledEvents();
}
public Dictionary<string, StringFeedback> CurrentPresetsFeedbacks { get; private set; }
public Dictionary<string, IRSetTopBoxBase> Tuners
{
get { return _tuners; }
}
public Dictionary<string, TwoWayDisplayBase> Displays
{
get { return _displays; }
}
public BoolFeedback RoomPowerIsOnFeedback { get; private set; }
public bool RoomPowerIsOn
{
get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); }
}
#region ITvPresetsProvider Members
public DevicePresetsModel TvPresets
{
get { return _tunerPresets; }
}
#endregion
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
{
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
if (!_currentPresets.ContainsKey(device.Key))
{
return;
}
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
_currentPresets[device.Key] = channel;
if (CurrentPresetsFeedbacks.ContainsKey(device.Key))
{
CurrentPresetsFeedbacks[device.Key].FireUpdate();
}
}
private void SetUpTunerPresetsFeedback()
{
_currentPresets = new Dictionary<string, string>();
CurrentPresetsFeedbacks = new Dictionary<string, StringFeedback>();
foreach (var setTopBox in _tuners)
{
var tuner = setTopBox.Value;
_currentPresets.Add(tuner.Key, String.Empty);
CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key]));
}
}
private void SubscribeToDisplayFeedbacks()
{
foreach (var display in _displays)
{
display.Value.PowerIsOnFeedback.OutputChange +=
(sender, args) =>
{
RoomPowerIsOnFeedback.InvokeFireUpdate();
IsWarmingUpFeedback.InvokeFireUpdate();
IsCoolingDownFeedback.InvokeFireUpdate();
};
}
}
private void CreateOrUpdateScheduledEvents()
{
var eventsConfig = PropertiesConfig.ScheduledEvents;
GetOrCreateScheduleGroup();
foreach (var eventConfig in eventsConfig)
{
CreateOrUpdateSingleEvent(eventConfig);
}
_roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent;
}
private void GetOrCreateScheduleGroup()
{
if (_roomScheduledEventGroup == null)
{
_roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key);
Scheduler.AddEventGroup(_roomScheduledEventGroup);
}
_roomScheduledEventGroup.RetrieveAllEvents();
}
private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent)
{
if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key))
{
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
return;
}
var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
//if (SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
// SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
//{
// Debug.Console(1, this, "Existing event matches new event properties. Nothing to update");
// return;
//}
Debug.Console(1, this,
"Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",
roomEvent.Name);
_roomScheduledEventGroup.DeleteEvent(roomEvent);
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
}
public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent)
{
//update config based on key of scheduleEvent
GetOrCreateScheduleGroup();
var existingEventIndex = PropertiesConfig.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
if (existingEventIndex < 0)
{
PropertiesConfig.ScheduledEvents.Add(scheduledEvent);
}
else
{
PropertiesConfig.ScheduledEvents[existingEventIndex] = scheduledEvent;
}
//create or update event based on config
CreateOrUpdateSingleEvent(scheduledEvent);
//save config
Config.Properties = JToken.FromObject(PropertiesConfig);
CustomSetConfig(Config);
//Fire Event
OnScheduledEventUpdate();
}
public List<ScheduledEventConfig> GetScheduledEvents()
{
return PropertiesConfig.ScheduledEvents ?? new List<ScheduledEventConfig>();
}
private void OnScheduledEventUpdate()
{
var handler = ScheduledEventsChanged;
if (handler == null)
{
return;
}
handler(this, new ScheduledEventEventArgs {ScheduledEvents = PropertiesConfig.ScheduledEvents});
}
public event EventHandler<ScheduledEventEventArgs> ScheduledEventsChanged;
private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
{
var eventConfig = PropertiesConfig.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
if (eventConfig == null)
{
Debug.Console(1, this, "Event with name {0} not found", schevent.Name);
return;
}
Debug.Console(1, this, "Running actions for event {0}", schevent.Name);
if (eventConfig.Acknowledgeable)
{
schevent.Acknowledge();
}
CrestronInvoke.BeginInvoke((o) =>
{
Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count);
foreach (var a in eventConfig.Actions)
{
Debug.Console(2, this,
@"Attempting to run action:
Key: {0}
MethodName: {1}
Params: {2}"
, a.DeviceKey, a.MethodName, a.Params);
DeviceJsonApi.DoDeviceAction(a);
}
});
}
public void RoomPowerOn()
{
Debug.Console(2, this, "Room Powering On");
var dummySource = DeviceManager.GetDeviceForKey(PropertiesConfig.DummySourceKey) as IRoutingOutputs;
if (dummySource == null)
{
Debug.Console(1, this, "Unable to get source with key: {0}", PropertiesConfig.DummySourceKey);
return;
}
foreach (var display in _displays)
{
RunDirectRoute(dummySource, display.Value);
}
}
public void RoomPowerOff()
{
Debug.Console(2, this, "Room Powering Off");
foreach (var display in _displays)
{
display.Value.PowerOff();
}
}
private Dictionary<string, T> GetDevices<T>(ICollection<string> config) where T : IKeyed
{
try
{
var returnValue = DeviceManager.AllDevices.OfType<T>()
.Where(d => config.Contains(d.Key))
.ToDictionary(d => d.Key, d => d);
return returnValue;
}
catch
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
"Error getting devices. Check Essentials Configuration");
return null;
}
}
#region Overrides of EssentialsRoomBase
protected override Func<bool> OnFeedbackFunc
{
get { return () => RoomPowerIsOn; }
}
protected override void EndShutdown()
{
}
public override void SetDefaultLevels()
{
}
public override void PowerOnToDefaultOrLastSource()
{
}
public override bool RunDefaultPresentRoute()
{
return false;
}
public override void RoomVacatedForTimeoutPeriod(object o)
{
}
#endregion
#region Implementation of IBridgeAdvanced
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new EssentialsTechRoomJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!String.IsNullOrEmpty(joinMapSerialized))
{
joinMap = JsonConvert.DeserializeObject<EssentialsTechRoomJoinMap>(joinMapSerialized);
}
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
if (PropertiesConfig.IsPrimary)
{
Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring");
if (PropertiesConfig.MirroredTuners != null && PropertiesConfig.MirroredTuners.Count > 0)
{
foreach (var tuner in PropertiesConfig.MirroredTuners)
{
var f = CurrentPresetsFeedbacks[tuner.Value];
if (f == null)
{
Debug.Console(1, this, "Unable to find feedback with key: {0}", tuner.Value);
continue;
}
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
f.LinkInputSig(trilist.StringInput[(uint)(join)]);
Debug.Console(1, this, "Linked Current Preset feedback for tuner: {0} to serial join: {1}", tuner.Value, join);
}
}
//i = 0;
//foreach (var feedback in CurrentPresetsFeedbacks)
//{
// feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]);
// i++;
//}
trilist.OnlineStatusChange += (device, args) =>
{
if (!args.DeviceOnLine)
{
return;
}
foreach (var feedback in CurrentPresetsFeedbacks)
{
feedback.Value.FireUpdate();
}
};
return;
}
else
{
Debug.Console(1, this, "Linking Secondary system Tuner Preset Mirroring");
if (PropertiesConfig.MirroredTuners != null && PropertiesConfig.MirroredTuners.Count > 0)
{
foreach (var tuner in PropertiesConfig.MirroredTuners)
{
var t = _tuners[tuner.Value];
if (t == null)
{
Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value);
continue;
}
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
trilist.SetStringSigAction(join, s => _tunerPresets.Dial(s, t));
Debug.Console(1, this, "Linked preset recall action for tuner: {0} to serial join: {1}", tuner.Value, join);
}
//foreach (var setTopBox in _tuners)
//{
// var tuner = setTopBox;
// trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value));
//}
}
}
}
#endregion
private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced
{
[JoinName("currentPreset")]
public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16},
new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial});
public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap))
{
}
}
#region IRunDirectRouteAction Members
private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest)
{
if (dest == null)
{
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key);
return;
}
if (source == null)
{
dest.ReleaseRoute();
if (dest is IHasPowerControl)
(dest as IHasPowerControl).PowerOff();
}
else
{
dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
}
}
/// <summary>
/// Attempts to route directly between a source and destination
/// </summary>
/// <param name="sourceKey"></param>
/// <param name="destinationKey"></param>
public void RunDirectRoute(string sourceKey, string destinationKey)
{
IRoutingSink dest = null;
dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink;
var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
if (source == null || dest == null)
{
Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey);
return;
}
RunDirectRoute(source, dest);
}
#endregion
}
public class ScheduledEventEventArgs : EventArgs
{
public List<ScheduledEventConfig> ScheduledEvents;
}
}

View File

@@ -1,24 +0,0 @@
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay, IHasCurrentVolumeControls
{
bool ExcludeFromGlobalFunctions { get; }
void RunRouteAction(string routeKey);
EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
IBasicVolumeControls CurrentVolumeControls { get; }
event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
}
}

View File

@@ -1,27 +0,0 @@
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials
{
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
{
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
bool ExcludeFromGlobalFunctions { get; }
void RunRouteAction(string routeKey);
IHasScheduleAwareness ScheduleSource { get; }
new BoolFeedback InCallFeedback { get; }
new BoolFeedback PrivacyModeIsOnFeedback { get; }
string DefaultCodecRouteString { get; }
}
}

View File

@@ -11,161 +11,135 @@ using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.PageManagers;
using PepperDash.Essentials.Core.UI;
using Newtonsoft.Json;
namespace PepperDash.Essentials
{
public class EssentialsTouchpanelController : TouchpanelBase
{
public class EssentialsTouchpanelController : EssentialsDevice, IHasBasicTriListWithSmartObject
{
public BasicTriListWithSmartObject Panel { get; private set; }
public PanelDriverBase PanelDriver { get; private set; }
CTimer BacklightTransitionedOnTimer;
public EssentialsTouchpanelController(string key, string name, Tswx52ButtonVoiceControl tsw,
string projectName, string sgdPath)
: base(key, name)
{
Panel = tsw;
tsw.LoadSmartObjects(sgdPath);
tsw.SigChange += Panel_SigChange;
}
public EssentialsTouchpanelController(string key, string name, Dge100 dge, string projectName, string sgdPath)
: base(key, name)
{
Panel = dge;
if (!string.IsNullOrEmpty(sgdPath))
dge.LoadSmartObjects(sgdPath);
else
Debug.Console(1, this, "No SGD file path defined");
dge.SigChange += Panel_SigChange;
}
/// <summary>
/// Config constructor
/// </summary>
public EssentialsTouchpanelController(string key, string name, BasicTriListWithSmartObject panel, CrestronTouchpanelPropertiesConfig config)
: base(key, name, panel, config)
public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id)
: base(key, name)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Creating touchpanel hardware...");
type = type.ToLower();
try
{
if (type == "crestronapp")
{
var app = new CrestronApp(id, Global.ControlSystem);
app.ParameterProjectName.Value = props.ProjectName;
Panel = app;
}
else if (type == "tsw550")
Panel = new Tsw550(id, Global.ControlSystem);
else if (type == "tsw552")
Panel = new Tsw552(id, Global.ControlSystem);
else if (type == "tsw560")
Panel = new Tsw560(id, Global.ControlSystem);
else if (type == "tsw750")
Panel = new Tsw750(id, Global.ControlSystem);
else if (type == "tsw752")
Panel = new Tsw752(id, Global.ControlSystem);
else if (type == "tsw760")
Panel = new Tsw760(id, Global.ControlSystem);
else if (type == "tsw1050")
Panel = new Tsw1050(id, Global.ControlSystem);
else if (type == "tsw1052")
Panel = new Tsw1052(id, Global.ControlSystem);
else if (type == "tsw1060")
Panel = new Tsw1060(id, Global.ControlSystem);
else
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
return;
}
}
catch (Exception e)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
return;
}
// Reserved sigs
if (Panel is TswFt5ButtonSystem)
{
var tsw = Panel as TswFt5ButtonSystem;
tsw.ExtenderSystemReservedSigs.Use();
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
}
if (Panel.Register() != eDeviceRegistrationUnRegistrationResponse.Success)
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "WARNING: Registration failed. Continuing, but panel may not function: {0}", Panel.RegistrationFailureReason);
// Give up cleanly if SGD is not present.
var sgdName = Global.FilePathPrefix + "sgd" + Global.DirectorySeparator + props.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "Smart object file '{0}' not present in User folder. Looking for embedded file", sgdName);
sgdName = Global.ApplicationDirectoryPathPrefix + Global.DirectorySeparator + "SGD" + Global.DirectorySeparator + props.SgdFile;
if (!File.Exists(sgdName))
{
Debug.Console(0, this, "Unable to find SGD file '{0}' in User sgd or application SGD folder. Exiting touchpanel load.", sgdName);
return;
}
}
Panel.LoadSmartObjects(sgdName);
Panel.SigChange += Panel_SigChange;
}
/// <summary>
/// Sets up drivers and links them to the room specified
/// </summary>
/// <param name="roomKey">key of room to link the drivers to</param>
protected override void SetupPanelDrivers(string roomKey)
{
// Clear out any existing actions
Panel.ClearAllSigActions();
Debug.Console(0, this, "Linking TP '{0}' to Room '{1}'", Key, roomKey);
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, _config);
// Then the sub drivers
// spin up different room drivers depending on room type
var room = DeviceManager.GetDeviceForKey(roomKey);
if (room is IEssentialsHuddleSpaceRoom)
{
// Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _config);
// Header Driver
Debug.Console(0, this, "Adding header driver");
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _config);
// AV Driver
Debug.Console(0, this, "Adding huddle space AV driver");
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, _config);
avDriver.DefaultRoomKey = roomKey;
mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as IEssentialsHuddleSpaceRoom;
// Environment Driver
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, this, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _config);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);
if (Panel is TswFt5ButtonSystem)
{
var tsw = Panel as TswFt5ButtonSystem;
// Wire up hard keys
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
if (mainDriver.EnvironmentDriver != null)
tsw.Lights.UserObject = new Action<bool>(b =>
{
if (!b)
{
mainDriver.EnvironmentDriver.Toggle();
}
});
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
}
}
else if (room is IEssentialsHuddleVtc1Room)
{
Debug.Console(0, this, "Adding huddle space VTC AV driver");
// Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, _config);
// Header Driver
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, _config);
// AV Driver
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, _config);
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(Panel, avDriver,
(room as IEssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
avDriver.SetVideoCodecDriver(codecDriver);
avDriver.DefaultRoomKey = roomKey;
mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as IEssentialsHuddleVtc1Room;
// Environment Driver
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, this, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, _config);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);
if (Panel is TswFt5ButtonSystem)
{
var tsw = Panel as TswFt5ButtonSystem;
// Wire up hard keys
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.EndMeetingPress(); });
if (mainDriver.EnvironmentDriver != null)
tsw.Lights.UserObject = new Action<bool>(b =>
{
if (!b)
{
mainDriver.EnvironmentDriver.Toggle();
}
});
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
}
LoadAndShowDriver(mainDriver);
}
else
{
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", roomKey);
}
}
public void LoadAndShowDriver(PanelDriverBase driver)
{
if (PanelDriver != null)
{
var mainDriver = PanelDriver as EssentialsPanelMainInterfaceDriver;
if (mainDriver != null)
{
mainDriver.Dispose();
}
}
PanelDriver = driver;
driver.Show();
}
protected override void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
void HomePressed()
{
if (BacklightTransitionedOnTimer == null)
PanelDriver.BackButtonPressed();
}
void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
{
// If the sig is transitioning on, mark it in case it was home button that transitioned it
var blOnSig = (Panel as TswFt5ButtonSystem).ExtenderSystemReservedSigs.BacklightOnFeedback;
@@ -203,86 +177,158 @@ namespace PepperDash.Essentials
act(value);
}
}
void Panel_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
{
if (Debug.Level == 2)
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
{
var uo = args.Button.UserObject;
if(uo is Action<bool>)
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
}
}
public class EssentialsTouchpanelControllerFactory : EssentialsDeviceFactory<EssentialsTouchpanelController>
{
public EssentialsTouchpanelControllerFactory()
{
TypeNames = new List<string>() { "crestronapp", "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "tsw570", "tsw770", "ts770", "tsw1070", "ts1070", "xpanel" };
TypeNames = new List<string>() { "tsw550", "tsw750", "tsw1050", "tsw560", "tsw760", "tsw1060", "xpanel" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
var comm = CommFactory.GetControlPropertiesConfig(dc);
var props = JsonConvert.DeserializeObject<CrestronTouchpanelPropertiesConfig>(dc.Properties.ToString());
var panel = GetPanelForType(dc.Type, comm.IpIdInt, props.ProjectName);
if (panel == null)
{
Debug.Console(0, "Unable to create Touchpanel for type {0}. Touchpanel Controller WILL NOT function correctly", dc.Type);
}
var props = Newtonsoft.Json.JsonConvert.DeserializeObject<CrestronTouchpanelPropertiesConfig>(dc.Properties.ToString());
Debug.Console(1, "Factory Attempting to create new EssentialsTouchpanelController");
var panelController = new EssentialsTouchpanelController(dc.Key, dc.Name, panel, props);
var panelController = new EssentialsTouchpanelController(dc.Key, dc.Name, dc.Type, props, comm.IpIdInt);
panelController.AddPostActivationAction(() =>
{
var mainDriver = new EssentialsPanelMainInterfaceDriver(panelController.Panel, props);
// Then the sub drivers
// spin up different room drivers depending on room type
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
if (room is EssentialsHuddleSpaceRoom)
{
// Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props);
// Header Driver
Debug.Console(0, panelController, "Adding header driver");
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props);
// AV Driver
Debug.Console(0, panelController, "Adding huddle space AV driver");
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
avDriver.DefaultRoomKey = props.DefaultRoomKey;
mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
// Environment Driver
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, panelController, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);
panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted.
if (panelController.Panel is TswFt5ButtonSystem)
{
var tsw = panelController.Panel as TswFt5ButtonSystem;
// Wire up hard keys
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
if (mainDriver.EnvironmentDriver != null)
tsw.Lights.UserObject = new Action<bool>(b =>
{
if (!b)
{
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
mainDriver.EnvironmentDriver.Toggle();
}
});
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
}
}
else if (room is EssentialsHuddleVtc1Room)
{
Debug.Console(0, panelController, "Adding huddle space VTC AV driver");
// Screen Saver Driver
mainDriver.ScreenSaverController = new ScreenSaverController(mainDriver, props);
// Header Driver
mainDriver.HeaderDriver = new EssentialsHeaderDriver(mainDriver, props);
// AV Driver
var avDriver = new EssentialsHuddleVtc1PanelAvFunctionsDriver(mainDriver, props);
var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver,
(room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver);
avDriver.SetVideoCodecDriver(codecDriver);
avDriver.DefaultRoomKey = props.DefaultRoomKey;
mainDriver.AvDriver = avDriver;
avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room;
// Environment Driver
if (avDriver.CurrentRoom.PropertiesConfig.Environment != null && avDriver.CurrentRoom.PropertiesConfig.Environment.DeviceKeys.Count > 0)
{
Debug.Console(0, panelController, "Adding environment driver");
mainDriver.EnvironmentDriver = new EssentialsEnvironmentDriver(mainDriver, props);
mainDriver.EnvironmentDriver.GetDevicesFromConfig(avDriver.CurrentRoom.PropertiesConfig.Environment);
}
mainDriver.HeaderDriver.SetupHeaderButtons(avDriver, avDriver.CurrentRoom);
panelController.LoadAndShowDriver(mainDriver); // This is a little convoluted.
if (panelController.Panel is TswFt5ButtonSystem)
{
var tsw = panelController.Panel as TswFt5ButtonSystem;
// Wire up hard keys
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.EndMeetingPress(); });
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
if (mainDriver.EnvironmentDriver != null)
tsw.Lights.UserObject = new Action<bool>(b =>
{
if (!b)
{
//mainDriver.AvDriver.PopupInterlock.ShowInterlockedWithToggle(mainDriver.EnvironmentDriver.BackgroundSubpageJoin);
mainDriver.EnvironmentDriver.Toggle();
}
});
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
}
}
else
{
Debug.Console(0, panelController, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
}
});
return panelController;
}
private BasicTriListWithSmartObject GetPanelForType(string type, uint id, string projectName)
{
type = type.ToLower();
try
{
if (type == "crestronapp")
{
var app = new CrestronApp(id, Global.ControlSystem);
app.ParameterProjectName.Value = projectName;
return app;
}
else if (type == "xpanel")
return new XpanelForSmartGraphics(id, Global.ControlSystem);
else if (type == "tsw550")
return new Tsw550(id, Global.ControlSystem);
else if (type == "tsw552")
return new Tsw552(id, Global.ControlSystem);
else if (type == "tsw560")
return new Tsw560(id, Global.ControlSystem);
else if (type == "tsw750")
return new Tsw750(id, Global.ControlSystem);
else if (type == "tsw752")
return new Tsw752(id, Global.ControlSystem);
else if (type == "tsw760")
return new Tsw760(id, Global.ControlSystem);
else if (type == "tsw1050")
return new Tsw1050(id, Global.ControlSystem);
else if (type == "tsw1052")
return new Tsw1052(id, Global.ControlSystem);
else if (type == "tsw1060")
return new Tsw1060(id, Global.ControlSystem);
else if (type == "tsw570")
return new Tsw570(id, Global.ControlSystem);
else if (type == "tsw770")
return new Tsw770(id, Global.ControlSystem);
else if (type == "ts770")
return new Ts770(id, Global.ControlSystem);
else if (type == "tsw1070")
return new Tsw1070(id, Global.ControlSystem);
else if (type == "ts1070")
return new Ts1070(id, Global.ControlSystem);
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW controller with type '{0}'", type);
return null;
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
return null;
}
}
}
}

View File

@@ -49,16 +49,6 @@ namespace PepperDash.Essentials
/// 1006
/// </summary>
public const uint CallEndAllConfirmVisible = 1006;
/// <summary>
/// 1007
/// </summary>
public const uint MeetingPasswordVisible = 1007;
/// <summary>
/// 1008
/// </summary>
public const uint MeetingLeavePress = 1008;
@@ -113,7 +103,7 @@ namespace PepperDash.Essentials
/// <summary>
/// 1202
/// </summary>
public const uint VCStagingInactivePopoverWithRecentsVisible = 1202;
public const uint VCStagingInactivePopoverVisible = 1202;
/// <summary>
///
/// </summary>
@@ -131,11 +121,6 @@ namespace PepperDash.Essentials
/// </summary>
public const uint VCRecentsVisible = 1206;
/// <summary>
/// 1202
/// </summary>
public const uint VCStagingInactivePopoverWithoutRecentsVisible = 1207;
/// <summary>
/// 1208
/// </summary>
@@ -163,11 +148,6 @@ namespace PepperDash.Essentials
public const uint VCFavoriteVisibleStart = 1221;
// RANGE IN USE
public const uint VCFavoriteVisibleEnd = 1225;
/// <summary>
/// 1230
/// </summary>
public const uint VCStagingMeetNowPress = 1230;
/// <summary>
/// 1231
/// </summary>
@@ -263,10 +243,6 @@ namespace PepperDash.Essentials
/// </summary>
public const uint VCCameraSelectBarWithoutModeVisible = 1261;
/// <summary>
/// 1262
/// </summary>
public const uint VCCameraAutoModeIsOnFb = 1262;
/// <summary>
/// 1271
@@ -768,9 +744,9 @@ namespace PepperDash.Essentials
/// </summary>
public const uint SourceBackgroundOverlayClosePress = 15044;
/// <summary>
/// 15045
/// 15045 - Visibility for the bar containing call navigation button list
/// </summary>
public const uint ZoomRoomContentSharingVisible = 15045;
public const uint CallStagingBarVisible = 15045;
/// <summary>
/// 15046
/// </summary>
@@ -788,10 +764,6 @@ namespace PepperDash.Essentials
/// </summary>
public const uint NextMeetingModalVisible = 15049;
/// <summary>
/// 15050
/// </summary>
public const uint NextMeetingNotificationRibbonVisible = 15050;
/// <summary>
/// 15051
/// </summary>
public const uint Display1SelectPressAndFb = 15051;
@@ -859,11 +831,6 @@ namespace PepperDash.Essentials
/// 15067
/// </summary>
public const uint NotificationRibbonVisible = 15067;
/// <summary>
/// 15068
/// </summary>
public const uint HeaderMeetingInfoVisible = 15068;
/// <summary>
/// 15083 - Press for Call help desk on AC/VC
/// </summary>
@@ -968,24 +935,5 @@ namespace PepperDash.Essentials
/// 15214
/// </summary>
public const uint PinDialogDot4 = 15214;
// Password Prompt Dialog **************************
/// <summary>
/// 15301
/// </summary>
public const uint PasswordPromptDialogVisible = 15301;
/// <summary>
/// 15302
/// </summary>
public const uint PasswordPromptTextPress = 15302;
/// <summary>
/// 15306
/// </summary>
public const uint PasswordPromptCancelPress = 15306;
/// <summary>
/// 15307
/// </summary>
public const uint PasswordPromptErrorVisible = 15307;
}
}

View File

@@ -27,33 +27,6 @@ namespace PepperDash.Essentials
/// 1004
/// </summary>
public const uint CallSharedSourceNameText = 1004;
/// <summary>
/// 1005
/// </summary>
public const uint MeetingIdText = 1005;
/// <summary>
/// 1006
/// </summary>
public const uint MeetingHostText = 1006;
/// <summary>
/// 1007
/// </summary>
public const uint MeetingPasswordText = 1007;
/// <summary>
/// 1008
/// </summary>
public const uint MeetingLeaveText = 1008;
/// <summary>
/// 1009
/// </summary>
public const uint MeetingNameText = 1009;
///<summary>
/// 1240 - Used to determine text for meeting start button
///</summary>
public const uint MeetingStartButtonText = 1240;
/// <summary>
@@ -145,14 +118,6 @@ namespace PepperDash.Essentials
//----- through 3120
/// <summary>
/// 3201
/// </summary>
public const uint PasswordPromptMessageText = 3201;
/// <summary>
/// 3202
/// </summary>
public const uint PasswordPromptPasswordText = 3202;
/// <summary>
/// 3812

View File

@@ -7,7 +7,7 @@
{
// Video Codec
/// <summary>
/// 1234: values 0 = Connect, 1 = End, 2 = Start Meeting
/// 1234: values 0 = Connect, 1 = End
/// </summary>
public const uint VCStagingConnectButtonMode = 1234;

View File

@@ -14,8 +14,6 @@ namespace PepperDash.Essentials
{
public SourceListItem SourceItem { get; private set; }
private IHasCurrentSourceInfoChange _room;
public SubpageReferenceListSourceItem(uint index, SubpageReferenceList owner,
SourceListItem sourceItem, Action<bool> routeAction)
: base(index, owner)
@@ -27,7 +25,6 @@ namespace PepperDash.Essentials
public void RegisterForSourceChange(IHasCurrentSourceInfoChange room)
{
_room = room;
room.CurrentSourceChange -= room_CurrentSourceInfoChange;
room.CurrentSourceChange += room_CurrentSourceInfoChange;
}
@@ -47,9 +44,6 @@ namespace PepperDash.Essentials
{
Owner.BoolInputSig(Index, 1).UserObject = null;
Owner.StringInputSig(Index, 1).StringValue = "";
if(_room != null)
_room.CurrentSourceChange -= room_CurrentSourceInfoChange;
}
/// <summary>

View File

@@ -146,18 +146,18 @@
// }
// void CurrentRoom_CurrentSourceInfoChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// void CurrentRoom_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// }
// void CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// void CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName;
// }
// void CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// void CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName;
// }

View File

@@ -111,7 +111,7 @@ namespace PepperDash.Essentials
/// <summary>
/// Reads the device keys from the config and gets the devices by key
/// </summary>
public void GetDevicesFromConfig(Room.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig)
public void GetDevicesFromConfig(Core.Rooms.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig)
{
if (EnvironmentPropertiesConfig != null)
{

View File

@@ -97,10 +97,10 @@ namespace PepperDash.Essentials
{
TriList.SetSigFalseAction(ButtonPressJoinBase + 1, ShadeDevice.Open);
TriList.SetSigFalseAction(ButtonPressJoinBase + 2, (ShadeDevice as IShadesOpenCloseStop).Stop);
if (ShadeDevice is IShadesOpenCloseStop)
TriList.SetString(StringJoinBase + 2, "Stop");
TriList.SetSigFalseAction(ButtonPressJoinBase + 2, (ShadeDevice as IShadesOpenCloseStop).StopOrPreset);
if(ShadeDevice is RelayControlledShade)
TriList.SetString(StringJoinBase + 2, (ShadeDevice as RelayControlledShade).StopOrPresetButtonLabel);
TriList.SetSigFalseAction(ButtonPressJoinBase + 3, ShadeDevice.Close);
}

View File

@@ -10,11 +10,11 @@ using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices.VideoCodec;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.PageManagers;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Core.Rooms.Config;
using PepperDash.Essentials.Core.Devices.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
@@ -53,7 +53,7 @@ namespace PepperDash.Essentials
CaretInterlock = new JoinedSigInterlock(TriList);
}
void SetUpGear(IAVDriver avDriver, IEssentialsRoom currentRoom)
void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom)
{
// Gear
TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear");
@@ -106,7 +106,7 @@ namespace PepperDash.Essentials
{
string message = null;
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
as IEssentialsHuddleSpaceRoom;
as EssentialsHuddleSpaceRoom;
if (room != null)
message = room.PropertiesConfig.HelpMessage;
else
@@ -165,7 +165,7 @@ namespace PepperDash.Essentials
CallCaretVisible = tempJoin + 10;
TriList.SetSigFalseAction(tempJoin, () =>
{
avDriver.ShowActiveCallsListOrMeetingInfo();
avDriver.ShowActiveCallsList();
if(avDriver.CurrentRoom.InCallFeedback.BoolValue)
CaretInterlock.ShowInterlocked(CallCaretVisible);
});
@@ -192,30 +192,26 @@ namespace PepperDash.Essentials
return;
}
var meetingInfoCodec = codec as IHasMeetingInfo;
// Set mode of header button
SetHeaderCallIcon(codec);
if (!codec.IsInCall)
{
HeaderCallButtonIconSig.StringValue = "DND";
//HeaderCallButton.SetIcon(HeaderListButton.OnHook);
}
else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
HeaderCallButtonIconSig.StringValue = "Misc-06_Dark";
//HeaderCallButton.SetIcon(HeaderListButton.Camera);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
else
HeaderCallButtonIconSig.StringValue = "Misc-09_Dark";
//HeaderCallButton.SetIcon(HeaderListButton.Phone);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
// Set the call status text
Debug.Console(1, "Active Call Count: {0}", codec.ActiveCalls.Count);
if (codec.ActiveCalls.Count > 0)
{
if (codec.ActiveCalls.Count == 1 && meetingInfoCodec == null)
if (codec.ActiveCalls.Count == 1)
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "1 Active Call");
else if (codec.ActiveCalls.Count == 1 && meetingInfoCodec != null)
{
var headerCallStatusLabel = meetingInfoCodec.MeetingInfo.IsSharingMeeting
? "Sharing-Only Meeting"
: "Active Meeting";
headerCallStatusLabel = meetingInfoCodec.MeetingInfo.WaitingForHost
? "Waiting For Host"
: headerCallStatusLabel;
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, headerCallStatusLabel);
}
else if (codec.ActiveCalls.Count > 1)
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, string.Format("{0} Active Calls", codec.ActiveCalls.Count));
}
@@ -223,31 +219,10 @@ namespace PepperDash.Essentials
TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "No Active Calls");
}
private void SetHeaderCallIcon(VideoCodecBase codec)
{
if (!codec.IsInCall)
{
HeaderCallButtonIconSig.StringValue = "DND";
//HeaderCallButton.SetIcon(HeaderListButton.OnHook);
}
else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
{
HeaderCallButtonIconSig.StringValue = "Misc-06_Dark";
}
//HeaderCallButton.SetIcon(HeaderListButton.Camera);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
else
{
HeaderCallButtonIconSig.StringValue = "Misc-09_Dark";
}
//HeaderCallButton.SetIcon(HeaderListButton.Phone);
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
}
/// <summary>
/// Sets up Header Buttons for the EssentialsHuddleVtc1Room type
/// </summary>
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, IEssentialsHuddleVtc1Room currentRoom)
public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom)
{
HeaderButtonsAreSetUp = false;
@@ -281,7 +256,7 @@ namespace PepperDash.Essentials
TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusLabelPress,
() =>
{
avDriver.ShowActiveCallsListOrMeetingInfo();
avDriver.ShowActiveCallsList();
if (avDriver.CurrentRoom.InCallFeedback.BoolValue)
CaretInterlock.ShowInterlocked(CallCaretVisible);
});
@@ -309,7 +284,7 @@ namespace PepperDash.Essentials
/// <summary>
/// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type
/// </summary>
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, IEssentialsHuddleSpaceRoom currentRoom)
public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom)
{
HeaderButtonsAreSetUp = false;
@@ -379,8 +354,6 @@ namespace PepperDash.Essentials
headerPopupShown = true;
else if (e.NewJoin == UIBoolJoin.HeaderActiveCallsListVisible)
headerPopupShown = true;
else if (e.NewJoin == UIBoolJoin.HeaderMeetingInfoVisible)
headerPopupShown = true;
else if (e.NewJoin == UIBoolJoin.HelpPageVisible)
headerPopupShown = true;
else if (e.NewJoin == UIBoolJoin.MeetingsOrContacMethodsListVisible)

View File

@@ -11,7 +11,7 @@ namespace PepperDash.Essentials
/// <summary>
///
/// </summary>
public class EssentialsPanelMainInterfaceDriver : PanelDriverBase, IHasScreenSaverController, IDisposable
public class EssentialsPanelMainInterfaceDriver : PanelDriverBase, IHasScreenSaverController
{
CTimer InactivityTimer;
@@ -69,35 +69,6 @@ namespace PepperDash.Essentials
}
}
#region IDisposable Members
public void Dispose()
{
var avDriver = AvDriver as PanelDriverBase;
if (avDriver != null)
{
avDriver.Hide();
}
if (ScreenSaverController != null)
{
ScreenSaverController.Dispose();
}
if (HeaderDriver != null)
{
HeaderDriver.Hide();
}
if (EnvironmentDriver != null)
{
EnvironmentDriver.Hide();
}
if (CurrentChildDriver != null)
{
CurrentChildDriver.Hide();
}
}
#endregion
void ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange(Crestron.SimplSharpPro.DeviceExtender currentDeviceExtender, Crestron.SimplSharpPro.SigEventArgs args)
{
@@ -159,7 +130,7 @@ namespace PepperDash.Essentials
if(CurrentChildDriver != null)
CurrentChildDriver.BackButtonPressed();
}
}
}
public interface IHasScreenSaverController
{

View File

@@ -983,7 +983,7 @@
// /// <summary>
// /// Handles source change
// /// </summary>
// void _CurrentRoom_SourceInfoChange(IEssentialsRoom room,
// void _CurrentRoom_SourceInfoChange(EssentialsRoomBase room,
// SourceListItem info, ChangeType change)
// {
// if (change == ChangeType.WillChange)
@@ -995,7 +995,7 @@
// /// <summary>
// ///
// /// </summary>
// void _CurrentRoom_CurrentDisplay1SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// void _CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// if (type == ChangeType.DidChange)
// {
@@ -1021,7 +1021,7 @@
// /// <summary>
// ///
// /// </summary>
// void _CurrentRoom_CurrentDisplay2SourceChange(IEssentialsRoom room, SourceListItem info, ChangeType type)
// void _CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// if (type == ChangeType.DidChange)
// {

View File

@@ -2,13 +2,11 @@
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.UI;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.PageManagers;
using PepperDash.Essentials.UIDrivers;
namespace PepperDash.Essentials
{
@@ -17,13 +15,18 @@ namespace PepperDash.Essentials
/// </summary>
public class EssentialsHuddlePanelAvFunctionsDriver : PanelDriverBase, IAVDriver
{
CrestronTouchpanelPropertiesConfig Config;
private readonly CrestronTouchpanelPropertiesConfig _config;
public enum UiDisplayMode
{
PresentationMode, AudioSetup
}
/// <summary>
/// The parent driver for this
/// </summary>
public PanelDriverBase Parent { get; private set; }
public uint StartPageVisibleJoin { get; private set; }
@@ -38,8 +41,8 @@ namespace PepperDash.Essentials
/// </summary>
public uint VolumeButtonPopupTimeout
{
get { return VolumeButtonsPopupFeedback.TimeoutMs; }
set { VolumeButtonsPopupFeedback.TimeoutMs = value; }
get { return _volumeButtonsPopupFeedback.TimeoutMs; }
set { _volumeButtonsPopupFeedback.TimeoutMs = value; }
}
/// <summary>
@@ -47,8 +50,8 @@ namespace PepperDash.Essentials
/// </summary>
public uint VolumeGaugePopupTimeout
{
get { return VolumeGaugeFeedback.TimeoutMs; }
set { VolumeGaugeFeedback.TimeoutMs = value; }
get { return _volumeGaugeFeedback.TimeoutMs; }
set { _volumeGaugeFeedback.TimeoutMs = value; }
}
/// <summary>
@@ -56,21 +59,12 @@ namespace PepperDash.Essentials
/// </summary>
public uint PowerOffTimeout { get; set; }
/// <summary>
///
/// </summary>
public string DefaultRoomKey
{
get { return _DefaultRoomKey; }
set
{
_DefaultRoomKey = value;
//CurrentRoom = DeviceManager.GetDeviceForKey(value) as EssentialsHuddleSpaceRoom;
}
}
string _DefaultRoomKey;
/// <summary>
///
/// </summary>
public string DefaultRoomKey { get; set; }
/// <summary>
/// <summary>
/// Indicates that the SetHeaderButtons method has completed successfully
/// </summary>
public bool HeaderButtonsAreSetUp { get; private set; }
@@ -78,15 +72,15 @@ namespace PepperDash.Essentials
/// <summary>
///
/// </summary>
public IEssentialsHuddleSpaceRoom CurrentRoom
public EssentialsHuddleSpaceRoom CurrentRoom
{
get { return _CurrentRoom; }
get { return _currentRoom; }
set
{
SetCurrentRoom(value);
}
}
IEssentialsHuddleSpaceRoom _CurrentRoom;
EssentialsHuddleSpaceRoom _currentRoom;
/// <summary>
///
@@ -96,88 +90,86 @@ namespace PepperDash.Essentials
/// <summary>
/// For hitting feedback
/// </summary>
BoolInputSig ShareButtonSig;
BoolInputSig EndMeetingButtonSig;
private readonly BoolInputSig _shareButtonSig;
private BoolInputSig _endMeetingButtonSig;
/// <summary>
/// Controls the extended period that the volume gauge shows on-screen,
/// as triggered by Volume up/down operations
/// </summary>
BoolFeedbackPulseExtender VolumeGaugeFeedback;
private readonly BoolFeedbackPulseExtender _volumeGaugeFeedback;
/// <summary>
/// Controls the period that the volume buttons show on non-hard-button
/// interfaces
/// </summary>
BoolFeedbackPulseExtender VolumeButtonsPopupFeedback;
private readonly BoolFeedbackPulseExtender _volumeButtonsPopupFeedback;
/// <summary>
/// The parent driver for this
/// </summary>
public PanelDriverBase Parent { get; private set; }
private readonly PanelDriverBase _parent;
/// <summary>
/// All children attached to this driver. For hiding and showing as a group.
/// </summary>
List<PanelDriverBase> ChildDrivers = new List<PanelDriverBase>();
private List<PanelDriverBase> _childDrivers = new List<PanelDriverBase>();
List<BoolInputSig> CurrentDisplayModeSigsInUse = new List<BoolInputSig>();
private readonly List<BoolInputSig> _currentDisplayModeSigsInUse = new List<BoolInputSig>();
//// Important smart objects
/// <summary>
/// Smart Object 3200
/// </summary>
SubpageReferenceList SourcesSrl;
private readonly SubpageReferenceList _sourcesSrl;
/// <summary>
/// Smart Object 15022
/// </summary>
SubpageReferenceList ActivityFooterSrl;
private readonly SubpageReferenceList _activityFooterSrl;
/// <summary>
/// Tracks which audio page group the UI is in
/// </summary>
UiDisplayMode CurrentDisplayMode;
private UiDisplayMode _currentDisplayMode;
/// <summary>
/// The AV page mangagers that have been used, to keep them alive for later
/// </summary>
Dictionary<object, PageManager> PageManagers = new Dictionary<object, PageManager>();
private readonly Dictionary<object, PageManager> _pageManagers = new Dictionary<object, PageManager>();
/// <summary>
/// Current page manager running for a source
/// </summary>
PageManager CurrentSourcePageManager;
private PageManager _currentSourcePageManager;
/// <summary>
/// Will auto-timeout a power off
/// </summary>
CTimer PowerOffTimer;
private CTimer _powerOffTimer;
ModalDialog PowerDownModal;
private ModalDialog _powerDownModal;
public JoinedSigInterlock PopupInterlock { get; private set; }
/// <summary>
/// The driver for the tech page. Lazy getter for memory usage
/// </summary>
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver TechDriver
EssentialsHuddleTechPageDriver TechDriver
{
get
{
if (_TechDriver == null)
_TechDriver = new PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech);
return _TechDriver;
get {
return _techDriver ??
(_techDriver = new EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech));
}
}
PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver _TechDriver;
private EssentialsHuddleTechPageDriver _techDriver;
/// <summary>
/// Controls timeout of notification ribbon timer
/// </summary>
CTimer RibbonTimer;
private CTimer _ribbonTimer;
/// <summary>
/// Constructor
@@ -185,25 +177,25 @@ namespace PepperDash.Essentials
public EssentialsHuddlePanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config)
: base(parent.TriList)
{
Config = config;
Parent = parent;
_config = config;
_parent = parent;
PopupInterlock = new JoinedSigInterlock(TriList);
SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
ActivityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
ShareButtonSig = ActivityFooterSrl.BoolInputSig(1, 1);
_sourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
_activityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
_shareButtonSig = _activityFooterSrl.BoolInputSig(1, 1);
SetupActivityFooterWhenRoomOff();
ShowVolumeGauge = true;
// One-second pulse extender for volume gauge
VolumeGaugeFeedback = new BoolFeedbackPulseExtender(1500);
VolumeGaugeFeedback.Feedback
_volumeGaugeFeedback = new BoolFeedbackPulseExtender(1500);
_volumeGaugeFeedback.Feedback
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VolumeGaugePopupVisible]);
VolumeButtonsPopupFeedback = new BoolFeedbackPulseExtender(4000);
VolumeButtonsPopupFeedback.Feedback
_volumeButtonsPopupFeedback = new BoolFeedbackPulseExtender(4000);
_volumeButtonsPopupFeedback.Feedback
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VolumeButtonPopupVisible]);
PowerOffTimeout = 30000;
@@ -224,9 +216,28 @@ namespace PepperDash.Essentials
return;
}
var roomConf = CurrentRoom.PropertiesConfig;
switch (_config.HeaderStyle.ToLower())
{
case CrestronTouchpanelPropertiesConfig.Habanero:
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, (() =>
{
if (CurrentRoom.IsMobileControlEnabled)
{
Debug.Console(1, "Showing Mobile Control Header Info");
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible);
}
else
{
Debug.Console(1, "Showing Non Mobile Control Header Info");
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible);
}
}));
break;
case CrestronTouchpanelPropertiesConfig.Verbose:
break;
}
if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero)
if (_config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero)
{
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
{
@@ -242,7 +253,7 @@ namespace PepperDash.Essentials
}
});
}
else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
else if (_config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose)
{
TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () =>
{
@@ -259,9 +270,9 @@ namespace PepperDash.Essentials
});
}
TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime);
TriList.SetBool(UIBoolJoin.DateOnlyVisible, Config.ShowDate && !Config.ShowTime);
TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !Config.ShowDate && Config.ShowTime);
TriList.SetBool(UIBoolJoin.DateAndTimeVisible, _config.ShowDate && _config.ShowTime);
TriList.SetBool(UIBoolJoin.DateOnlyVisible, _config.ShowDate && !_config.ShowTime);
TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !_config.ShowDate && _config.ShowTime);
TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true);
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = true;
@@ -306,7 +317,7 @@ namespace PepperDash.Essentials
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
{
if (CurrentRoom != null && CurrentRoom.DefaultDisplay != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
});
@@ -348,8 +359,8 @@ namespace PepperDash.Essentials
{
TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false);
TriList.SetBool(UIBoolJoin.LogoUrlVisible, true);
TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlLightBkgnd);
TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _CurrentRoom.LogoUrlDarkBkgnd);
TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _currentRoom.LogoUrlLightBkgnd);
TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _currentRoom.LogoUrlDarkBkgnd);
}
}
@@ -374,7 +385,7 @@ namespace PepperDash.Essentials
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
//TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
VolumeButtonsPopupFeedback.ClearNow();
_volumeButtonsPopupFeedback.ClearNow();
//CancelPowerOff();
base.Hide();
@@ -391,12 +402,12 @@ namespace PepperDash.Essentials
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, true);
if (timeout > 0)
{
if (RibbonTimer != null)
RibbonTimer.Stop();
RibbonTimer = new CTimer(o =>
if (_ribbonTimer != null)
_ribbonTimer.Stop();
_ribbonTimer = new CTimer(o =>
{
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false);
RibbonTimer = null;
_ribbonTimer = null;
}, timeout);
}
}
@@ -407,10 +418,10 @@ namespace PepperDash.Essentials
public void HideNotificationRibbon()
{
TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false);
if (RibbonTimer != null)
if (_ribbonTimer != null)
{
RibbonTimer.Stop();
RibbonTimer = null;
_ribbonTimer.Stop();
_ribbonTimer = null;
}
}
@@ -422,7 +433,7 @@ namespace PepperDash.Essentials
{
//Clear whatever is showing now.
HideAndClearCurrentDisplayModeSigsInUse();
CurrentDisplayMode = mode;
_currentDisplayMode = mode;
switch (mode)
{
case UiDisplayMode.PresentationMode:
@@ -440,7 +451,7 @@ namespace PepperDash.Essentials
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
}
// Date/time
if (Config.ShowDate && Config.ShowTime)
if (_config.ShowDate && _config.ShowTime)
{
TriList.BooleanInput[UIBoolJoin.DateAndTimeVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = false;
@@ -449,8 +460,8 @@ namespace PepperDash.Essentials
else
{
TriList.BooleanInput[UIBoolJoin.DateAndTimeVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = Config.ShowDate;
TriList.BooleanInput[UIBoolJoin.TimeOnlyVisible].BoolValue = Config.ShowTime;
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = _config.ShowDate;
TriList.BooleanInput[UIBoolJoin.TimeOnlyVisible].BoolValue = _config.ShowTime;
}
ShowCurrentDisplayModeSigsInUse();
@@ -463,12 +474,12 @@ namespace PepperDash.Essentials
/// </summary>
void SetupActivityFooterWhenRoomOff()
{
ActivityFooterSrl.Clear();
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0,
_activityFooterSrl.Clear();
_activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, _activityFooterSrl, 0,
b => { if (!b) ShareButtonPressed(); }));
ActivityFooterSrl.Count = 1;
_activityFooterSrl.Count = 1;
TriList.UShortInput[UIUshortJoin.PresentationStagingCaretMode].UShortValue = 0;
ShareButtonSig.BoolValue = false;
_shareButtonSig.BoolValue = false;
}
/// <summary>
@@ -476,15 +487,15 @@ namespace PepperDash.Essentials
/// </summary>
void SetupActivityFooterWhenRoomOn()
{
ActivityFooterSrl.Clear();
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl,
_activityFooterSrl.Clear();
_activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, _activityFooterSrl,
0, null));
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl,
_activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, _activityFooterSrl,
4, b => { if (!b) PowerButtonPressed(); }));
ActivityFooterSrl.Count = 2;
_activityFooterSrl.Count = 2;
TriList.UShortInput[UIUshortJoin.PresentationStagingCaretMode].UShortValue = 1;
EndMeetingButtonSig = ActivityFooterSrl.BoolInputSig(2, 1);
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
_endMeetingButtonSig = _activityFooterSrl.BoolInputSig(2, 1);
_shareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
}
/// <summary>
@@ -492,13 +503,13 @@ namespace PepperDash.Essentials
/// </summary>
void ShareButtonPressed()
{
ShareButtonSig.BoolValue = true;
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false;
_shareButtonSig.BoolValue = true;
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
// Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue)
(CurrentRoom as IRunDefaultPresentRoute).RunDefaultPresentRoute();
CurrentRoom.RunDefaultPresentRoute();
}
@@ -507,7 +518,7 @@ namespace PepperDash.Essentials
/// </summary>
void ShowCurrentDisplayModeSigsInUse()
{
foreach (var sig in CurrentDisplayModeSigsInUse)
foreach (var sig in _currentDisplayModeSigsInUse)
sig.BoolValue = true;
}
@@ -516,9 +527,9 @@ namespace PepperDash.Essentials
/// </summary>
void HideAndClearCurrentDisplayModeSigsInUse()
{
foreach (var sig in CurrentDisplayModeSigsInUse)
foreach (var sig in _currentDisplayModeSigsInUse)
sig.BoolValue = false;
CurrentDisplayModeSigsInUse.Clear();
_currentDisplayModeSigsInUse.Clear();
}
/// <summary>
@@ -526,7 +537,7 @@ namespace PepperDash.Essentials
/// </summary>
public override void BackButtonPressed()
{
switch (CurrentDisplayMode)
switch (_currentDisplayMode)
{
case UiDisplayMode.PresentationMode:
//CancelReturnToSourceTimer();
@@ -541,7 +552,7 @@ namespace PepperDash.Essentials
void BackToHome()
{
Hide();
Parent.Show();
_parent.Show();
}
/// <summary>
@@ -553,26 +564,28 @@ namespace PepperDash.Essentials
return;
var uiDev = CurrentRoom.CurrentSourceInfo.SourceDevice as IUiDisplayInfo;
PageManager pm = null;
// If we need a page manager, get an appropriate one
if (uiDev != null)
{
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
// Got an existing page manager, get it
if (PageManagers.ContainsKey(uiDev))
pm = PageManagers[uiDev];
// Otherwise make an apporiate one
else if (uiDev is ISetTopBoxControls)
//pm = new SetTopBoxMediumPageManager(uiDev as ISetTopBoxControls, TriList);
pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList);
else if (uiDev is IDiscPlayerControls)
pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList);
else
pm = new DefaultPageManager(uiDev, TriList);
PageManagers[uiDev] = pm;
CurrentSourcePageManager = pm;
pm.Show();
}
// If we need a page manager, get an appropriate one
if (uiDev == null)
{
return;
}
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
// Got an existing page manager, get it
PageManager pm;
if (_pageManagers.ContainsKey(uiDev))
pm = _pageManagers[uiDev];
// Otherwise make an apporiate one
else if (uiDev is ISetTopBoxControls)
//pm = new SetTopBoxMediumPageManager(uiDev as ISetTopBoxControls, TriList);
pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList);
else if (uiDev is IDiscPlayerControls)
pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList);
else
pm = new DefaultPageManager(uiDev, TriList);
_pageManagers[uiDev] = pm;
_currentSourcePageManager = pm;
pm.Show();
}
/// <summary>
@@ -583,7 +596,7 @@ namespace PepperDash.Essentials
void UiSelectSource(string key)
{
// Run the route and when it calls back, show the source
CurrentRoom.RunRouteAction(key);
CurrentRoom.RunRouteAction(key, () => { });
}
/// <summary>
@@ -607,12 +620,12 @@ namespace PepperDash.Essentials
{
// Do we need to check where the UI is? No?
var timer = CurrentRoom.ShutdownPromptTimer;
EndMeetingButtonSig.BoolValue = true;
ShareButtonSig.BoolValue = false;
_endMeetingButtonSig.BoolValue = true;
_shareButtonSig.BoolValue = false;
if (CurrentRoom.ShutdownType == eShutdownType.Manual || CurrentRoom.ShutdownType == eShutdownType.Vacancy)
{
PowerDownModal = new ModalDialog(TriList);
_powerDownModal = new ModalDialog(TriList);
var message = string.Format("Meeting will end in {0} seconds", CurrentRoom.ShutdownPromptSeconds);
// Attach timer things to modal
@@ -626,15 +639,15 @@ namespace PepperDash.Essentials
{
if (!onFb.BoolValue)
{
EndMeetingButtonSig.BoolValue = false;
PowerDownModal.HideDialog();
_endMeetingButtonSig.BoolValue = false;
_powerDownModal.HideDialog();
onFb.OutputChange -= offHandler;
//gauge.OutputChange -= gaugeHandler;
}
};
onFb.OutputChange += offHandler;
PowerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
_powerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
but =>
{
if (but != 2) // any button except for End cancels
@@ -652,7 +665,7 @@ namespace PepperDash.Essentials
/// <param name="e"></param>
void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
{
EndMeetingButtonSig.BoolValue = false;
_endMeetingButtonSig.BoolValue = false;
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange -= ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
}
@@ -664,10 +677,10 @@ namespace PepperDash.Essentials
/// <param name="e"></param>
void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
{
if (PowerDownModal != null)
PowerDownModal.HideDialog();
EndMeetingButtonSig.BoolValue = false;
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
if (_powerDownModal != null)
_powerDownModal.HideDialog();
_endMeetingButtonSig.BoolValue = false;
_shareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
@@ -675,27 +688,38 @@ namespace PepperDash.Essentials
void ShutdownPromptTimer_TimeRemainingFeedback_OutputChange(object sender, EventArgs e)
{
var stringFeedback = sender as StringFeedback;
if (stringFeedback == null)
{
return;
}
var message = string.Format("Meeting will end in {0} seconds", (sender as StringFeedback).StringValue);
var message = string.Format("Meeting will end in {0} seconds", stringFeedback.StringValue);
TriList.StringInput[ModalDialog.MessageTextJoin].StringValue = message;
}
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
{
var value = (ushort)((sender as IntFeedback).UShortValue * 65535 / 100);
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
}
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
{
var intFeedback = sender as IntFeedback;
if (intFeedback == null)
{
return;
}
var value = (ushort)(intFeedback.UShortValue * 65535 / 100);
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
}
/// <summary>
/// <summary>
///
/// </summary>
void CancelPowerOffTimer()
{
if (PowerOffTimer != null)
{
PowerOffTimer.Stop();
PowerOffTimer = null;
}
if (_powerOffTimer == null)
{
return;
}
_powerOffTimer.Stop();
_powerOffTimer = null;
}
/// <summary>
@@ -703,13 +727,13 @@ namespace PepperDash.Essentials
/// </summary>
void VolumeButtonsTogglePress()
{
if (VolumeButtonsPopupFeedback.BoolValue)
VolumeButtonsPopupFeedback.ClearNow();
if (_volumeButtonsPopupFeedback.BoolValue)
_volumeButtonsPopupFeedback.ClearNow();
else
{
// Trigger the popup
VolumeButtonsPopupFeedback.BoolValue = true;
VolumeButtonsPopupFeedback.BoolValue = false;
_volumeButtonsPopupFeedback.BoolValue = true;
_volumeButtonsPopupFeedback.BoolValue = false;
}
}
@@ -721,8 +745,8 @@ namespace PepperDash.Essentials
{
// extend timeouts
if (ShowVolumeGauge)
VolumeGaugeFeedback.BoolValue = state;
VolumeButtonsPopupFeedback.BoolValue = state;
_volumeGaugeFeedback.BoolValue = state;
_volumeButtonsPopupFeedback.BoolValue = state;
if (CurrentRoom.CurrentVolumeControls != null)
CurrentRoom.CurrentVolumeControls.VolumeUp(state);
}
@@ -735,8 +759,8 @@ namespace PepperDash.Essentials
{
// extend timeouts
if (ShowVolumeGauge)
VolumeGaugeFeedback.BoolValue = state;
VolumeButtonsPopupFeedback.BoolValue = state;
_volumeGaugeFeedback.BoolValue = state;
_volumeButtonsPopupFeedback.BoolValue = state;
if (CurrentRoom.CurrentVolumeControls != null)
CurrentRoom.CurrentVolumeControls.VolumeDown(state);
}
@@ -745,33 +769,33 @@ namespace PepperDash.Essentials
/// <summary>
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
/// </summary>
public void RefreshCurrentRoom(IEssentialsHuddleSpaceRoom room)
public void RefreshCurrentRoom(EssentialsHuddleSpaceRoom room)
{
if (_CurrentRoom != null)
if (_currentRoom != null)
{
// Disconnect current room
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
_currentRoom.CurrentVolumeDeviceChange -= CurrentRoom_CurrentAudioDeviceChange;
ClearAudioDeviceConnections();
_CurrentRoom.CurrentSourceChange -= this.CurrentRoom_SourceInfoChange;
DisconnectSource(_CurrentRoom.CurrentSourceInfo);
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
_CurrentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
_currentRoom.CurrentSourceChange -= CurrentRoom_SourceInfoChange;
DisconnectSource(_currentRoom.CurrentSourceInfo);
_currentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
_currentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
_currentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
_CurrentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange;
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
_currentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange;
_currentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
_currentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
}
_CurrentRoom = room;
_currentRoom = room;
if (_CurrentRoom != null)
if (_currentRoom != null)
{
// get the source list config and set up the source list
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
if (config.ContainsKey(_currentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey];
var srcList = config[_currentRoom.SourceListKey];
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
@@ -788,16 +812,16 @@ namespace PepperDash.Essentials
continue;
}
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
var item = new SubpageReferenceListSourceItem(i++, _sourcesSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourcesSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
_sourcesSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_currentRoom);
}
SourcesSrl.Count = (ushort)(i - 1);
_sourcesSrl.Count = (ushort)(i - 1);
}
// Name and logo
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
if (_CurrentRoom.LogoUrlLightBkgnd == null)
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _currentRoom.Name;
if (_currentRoom.LogoUrlLightBkgnd == null)
{
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = false;
@@ -806,28 +830,33 @@ namespace PepperDash.Essentials
{
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true;
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrlLightBkgnd;
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _CurrentRoom.LogoUrlDarkBkgnd;
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _currentRoom.LogoUrlLightBkgnd;
TriList.StringInput[UIStringJoin.LogoUrlLightBkgnd].StringValue = _currentRoom.LogoUrlDarkBkgnd;
}
// Shutdown timer
_CurrentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
_CurrentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
_currentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
_currentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
_currentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
// Link up all the change events from the room
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
_currentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
CurrentRoom_SyncOnFeedback();
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
_currentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
_currentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
_currentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
_CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
_currentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange;
RefreshSourceInfo();
(Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
var essentialsPanelMainInterfaceDriver = _parent as EssentialsPanelMainInterfaceDriver;
if (essentialsPanelMainInterfaceDriver != null)
{
essentialsPanelMainInterfaceDriver.HeaderDriver.SetupHeaderButtons(this, CurrentRoom);
}
}
else
{
@@ -836,13 +865,13 @@ namespace PepperDash.Essentials
}
}
void SetCurrentRoom(IEssentialsHuddleSpaceRoom room)
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
{
if (_CurrentRoom == room) return;
if (_currentRoom == room) return;
// Disconnect current (probably never called)
if (_CurrentRoom != null)
_CurrentRoom.ConfigChanged -= room_ConfigChanged;
if (_currentRoom != null)
_currentRoom.ConfigChanged -= room_ConfigChanged;
room.ConfigChanged -= room_ConfigChanged;
room.ConfigChanged += room_ConfigChanged;
@@ -852,8 +881,8 @@ namespace PepperDash.Essentials
StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible;
UpdateMCJoins(room);
if (_CurrentRoom != null)
_CurrentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged;
if (_currentRoom != null)
_currentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged;
room.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged;
room.MobileControlRoomBridge.UserCodeChanged += MobileControlRoomBridge_UserCodeChanged;
@@ -868,10 +897,10 @@ namespace PepperDash.Essentials
void MobileControlRoomBridge_UserCodeChanged(object sender, EventArgs e)
{
UpdateMCJoins(_CurrentRoom);
UpdateMCJoins(_currentRoom);
}
void UpdateMCJoins(IEssentialsHuddleSpaceRoom room)
void UpdateMCJoins(EssentialsHuddleSpaceRoom room)
{
TriList.SetString(UIStringJoin.RoomMcUrl, room.MobileControlRoomBridge.McServerUrl);
TriList.SetString(UIStringJoin.RoomMcQrCodeUrl, room.MobileControlRoomBridge.QrCodeUrl);
@@ -885,7 +914,7 @@ namespace PepperDash.Essentials
/// <param name="e"></param>
void room_ConfigChanged(object sender, EventArgs e)
{
RefreshCurrentRoom(_CurrentRoom);
RefreshCurrentRoom(_currentRoom);
}
/// <summary>
@@ -898,7 +927,7 @@ namespace PepperDash.Essentials
void CurrentRoom_SyncOnFeedback()
{
var value = _CurrentRoom.OnFeedback.BoolValue;
var value = _currentRoom.OnFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: Is on event={0}", value);
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
@@ -918,7 +947,6 @@ namespace PepperDash.Essentials
TriList.BooleanInput[StartPageVisibleJoin].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
}
}
@@ -961,15 +989,14 @@ namespace PepperDash.Essentials
// Hide whatever is showing
if (IsVisible)
{
if (CurrentSourcePageManager != null)
if (_currentSourcePageManager != null)
{
CurrentSourcePageManager.Hide();
CurrentSourcePageManager = null;
_currentSourcePageManager.Hide();
_currentSourcePageManager = null;
}
}
if (previousInfo == null) return;
var previousDev = previousInfo.SourceDevice;
var previousDev = previousInfo.SourceDevice;
// device type interfaces
if (previousDev is ISetTopBoxControls)
@@ -1000,7 +1027,7 @@ namespace PepperDash.Essentials
{
var routeInfo = CurrentRoom.CurrentSourceInfo;
// This will show off popup too
if (this.IsVisible)
if (IsVisible)
ShowCurrentSource();
if (routeInfo == null)// || !CurrentRoom.OnFeedback.BoolValue)
@@ -1008,22 +1035,23 @@ namespace PepperDash.Essentials
// Check for power off and insert "Room is off"
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "Room is off";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Power";
this.Hide();
Parent.Show();
Hide();
_parent.Show();
return;
}
else if (CurrentRoom.CurrentSourceInfo != null)
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName;
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank"
}
else
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank";
}
// Connect controls
if (CurrentRoom.CurrentSourceInfo != null)
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName;
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank"
}
else
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank";
}
// Connect controls
if (routeInfo.SourceDevice != null)
ConnectControlDeviceMethods(routeInfo.SourceDevice);
}

View File

@@ -8,12 +8,12 @@ using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
using PepperDash.Essentials.Devices.Displays;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Core.Rooms.Config;
namespace PepperDash.Essentials.UIDrivers
{
@@ -316,7 +316,7 @@ namespace PepperDash.Essentials.UIDrivers
void CommunicationMonitor_StatusChange(object sender, MonitorStatusChangeEventArgs e)
{
var c = sender as ICommunicationMonitor;
if (c != null && StatusListDeviceIndexes.ContainsKey(c))
if (StatusListDeviceIndexes.ContainsKey(c))
{
var i = StatusListDeviceIndexes[c];
StatusList.UShortInputSig(i, 1).UShortValue = (ushort)e.Status;

View File

@@ -52,7 +52,7 @@ namespace PepperDash.Essentials
{
var prevJoin = CurrentJoin;
var wasShown = _IsShown;
//Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
if (CurrentJoin == join && TriList.BooleanInput[join].BoolValue)
return;
SetButDontShow(join);
@@ -71,7 +71,7 @@ namespace PepperDash.Essentials
var prevJoin = CurrentJoin;
var wasShown = IsShown;
//Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join);
if (CurrentJoin == join)
HideAndClear();
else
@@ -92,7 +92,7 @@ namespace PepperDash.Essentials
{
var prevJoin = CurrentJoin;
var wasShown = IsShown;
//Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
Hide();
CurrentJoin = 0;
@@ -108,7 +108,7 @@ namespace PepperDash.Essentials
var prevJoin = CurrentJoin;
var wasShown = IsShown;
//Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin);
if (CurrentJoin > 0)
{
TriList.BooleanInput[CurrentJoin].BoolValue = false;
@@ -125,7 +125,7 @@ namespace PepperDash.Essentials
var prevJoin = CurrentJoin;
var wasShown = IsShown;
//Debug.Console(2, "Trilist {0:X2}, interlock showing {1}", TriList.ID, CurrentJoin);
Debug.Console(2, "Trilist {0:X2}, interlock showing {1}", TriList.ID, CurrentJoin);
if (CurrentJoin > 0)
{
TriList.BooleanInput[CurrentJoin].BoolValue = true;

View File

@@ -12,7 +12,7 @@ namespace PepperDash.Essentials
/// <summary>
/// Driver responsible for controlling the screenshaver showing the client logo, MC connection information and QR Code. Moves the elements around to prevent screen burn in
/// </summary>
public class ScreenSaverController : PanelDriverBase, IDisposable
public class ScreenSaverController : PanelDriverBase
{
/// <summary>
@@ -42,7 +42,7 @@ namespace PepperDash.Essentials
PositionInterlock = new JoinedSigInterlock(parent.TriList);
var cmdName = String.Format("shwscrsvr-{0:X2}", parent.TriList.ID);
var cmdName = String.Format("shwscrsvr-{0}", parent.TriList.ID);
CrestronConsole.AddNewConsoleCommand((o) => Show(), cmdName, "Shows Panel Screensaver", ConsoleAccessLevelEnum.AccessOperator);
@@ -51,8 +51,6 @@ namespace PepperDash.Essentials
public override void Show()
{
//Debug.Console(2, "Showing ScreenSaverController: {0:X2}", TriList.ID);
if (_parent.AvDriver != null)
{
_parent.AvDriver.PopupInterlock.ShowInterlocked(UIBoolJoin.MCScreenSaverVisible);
@@ -67,11 +65,10 @@ namespace PepperDash.Essentials
public override void Hide()
{
//Debug.Console(2, "Hiding ScreenSaverController: {0:X2}", TriList.ID);
Debug.Console(1, "Hiding ScreenSaverController");
if (PositionTimer != null)
{
//Debug.Console(2, "Stopping PositionTimer: {0:X2}", TriList.ID);
PositionTimer.Stop();
PositionTimer.Dispose();
PositionTimer = null;
@@ -89,8 +86,6 @@ namespace PepperDash.Essentials
void StartPositionTimer()
{
//Debug.Console(2, "Starting Position Timer: {0:X2}", TriList.ID);
if (PositionTimer == null)
{
PositionTimer = new CTimer((o) => PositionTimerExpired(), PositionTimeoutMs);
@@ -122,7 +117,7 @@ namespace PepperDash.Essentials
CurrentPositionIndex = 0;
}
//Debug.Console(2, "ScreenSaver Position Timer Expired: Setting new position: {0} ID: {1:X2}", CurrentPositionIndex, TriList.ID);
Debug.Console(1, "ScreenSaver Position Timer Expired: Setting new position: {0}", CurrentPositionIndex);
}
//
@@ -134,19 +129,9 @@ namespace PepperDash.Essentials
void ClearAllPositions()
{
//Debug.Console(2, "Hiding all screensaver positions: {0:X2}", TriList.ID);
Debug.Console(1, "Hiding all screensaver positions");
PositionInterlock.HideAndClear();
}
#region IDisposable Members
public void Dispose()
{
Hide();
}
#endregion
}
}

View File

@@ -38,7 +38,7 @@ namespace PepperDash.Essentials
/// <summary>
/// Sets feedback for the given room
/// </summary>
public void SetFeedbackForRoom(IEssentialsHuddleSpaceRoom room)
public void SetFeedbackForRoom(EssentialsHuddleSpaceRoom room)
{
var itemToSet = Items.FirstOrDefault(i => i.Room == room);
if (itemToSet != null)
@@ -48,11 +48,11 @@ namespace PepperDash.Essentials
public class SmartObjectRoomsListItem
{
public IEssentialsHuddleSpaceRoom Room { get; private set; }
public EssentialsHuddleSpaceRoom Room { get; private set; }
SmartObjectRoomsList Parent;
public uint Index { get; private set; }
public SmartObjectRoomsListItem(IEssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent,
public SmartObjectRoomsListItem(EssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent,
Action<bool> buttonAction)
{
Room = room;

View File

@@ -12,5 +12,5 @@ namespace PepperDash.Essentials
///// <summary>
///// The handler type for a Room's SourceInfoChange
///// </summary>
//public delegate void SourceInfoChangeHandler(IEssentialsRoom room, SourceListItem info, ChangeType type);
//public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
@@ -11,12 +10,14 @@ using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices.VideoCodec;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
using PepperDash.Essentials.Core.Devices.Codec;
using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
using PepperDash.Essentials.Devices.Common.Cameras;
using PepperDash.Essentials.Devices.Core.VideoCodec;
namespace PepperDash.Essentials.UIDrivers.VC
{
@@ -85,9 +86,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
StringBuilder SearchStringBuilder = new StringBuilder();
BoolFeedback SearchStringBackspaceVisibleFeedback;
StringFeedback PasswordStringFeedback;
StringBuilder PasswordStringBuilder = new StringBuilder();
ModalDialog IncomingCallModal;
eKeypadMode KeypadMode;
@@ -128,24 +126,26 @@ namespace PepperDash.Essentials.UIDrivers.VC
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(Codec_CallStatusChange);
// If the codec is ready, then get the values we want, otherwise wait
if (Codec.IsReady)
Codec_IsReady();
else
codec.IsReadyChange += (o, a) => Codec_IsReady();
//InCall = new BoolFeedback(() => false);
LocalPrivacyIsMuted = new BoolFeedback(() => false);
VCControlsInterlock = new JoinedSigInterlock(triList);
VCCameraControlModeInterlock = new JoinedSigInterlock(triList);
VCControlsInterlock.HideAndClear();
/* if (CodecHasFavorites || codec is IHasZoomRoomLayouts) //Checking for Zoom Room...picked a ZoomRoom specific interface to check for
if (CodecHasFavorites)
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadWithFavoritesVisible);
else
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible); */
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible);
StagingBarsInterlock = new JoinedSigInterlock(triList);
if(Codec is IHasCallHistory)
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible);
else
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible);
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible);
StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList);
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
@@ -153,8 +153,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
// Return formatted when dialing, straight digits when in call
DialStringFeedback = new StringFeedback(() =>
{
// Format the number feedback if in dial mode and the codec is not IHasStartMeeting (ZoomRoom)
if (KeypadMode == eKeypadMode.Dial && !(Codec is IHasStartMeeting))
if (KeypadMode == eKeypadMode.Dial)
return GetFormattedDialString(DialStringBuilder.ToString());
else
return DialStringBuilder.ToString();
@@ -181,23 +180,9 @@ namespace PepperDash.Essentials.UIDrivers.VC
});
SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]);
PasswordStringFeedback = new StringFeedback(() =>
{
if (PasswordStringBuilder.Length > 0)
{
Parent.Keyboard.EnableGoButton();
return PasswordStringBuilder.ToString();
}
else
{
Parent.Keyboard.DisableGoButton();
return "";
}
});
PasswordStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.PasswordPromptPasswordText]);
SetupDirectoryList();
SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0);
SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]);
@@ -214,18 +199,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
triList.SetSigHeldAction(UIBoolJoin.VCDirectoryBackspacePress, 500,
StartSearchBackspaceRepeat, StopSearchBackspaceRepeat, SearchKeypadBackspacePress);
if (Codec is IPasswordPrompt)
{
SetupPasswordPrompt();
}
// If the codec is ready, then get the values we want, otherwise wait
if (Codec.IsReady)
Codec_IsReady();
else
codec.IsReadyChange += (o, a) => Codec_IsReady();
}
catch (Exception e)
{
@@ -321,20 +294,24 @@ namespace PepperDash.Essentials.UIDrivers.VC
void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
{
var call = e.CallItem;
var meetingInfoSender = sender as IHasMeetingInfo;
switch (e.CallItem.Status)
{
case eCodecCallStatus.Connected:
// fire at SRL item
KeypadMode = eKeypadMode.DTMF;
DialStringBuilder.Remove(0, DialStringBuilder.Length);
DialStringFeedback.FireUpdate();
DialStringTextCheckEnables();
Parent.ShowNotificationRibbon("Connected", 2000);
OnCallConnected();
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
ShowKeypad();
((Parent.CurrentRoom as IHasCurrentVolumeControls).CurrentVolumeControls as IBasicVolumeWithFeedback).MuteOff();
//VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible);
break;
case eCodecCallStatus.Connecting:
// fire at SRL item
Parent.ShowNotificationRibbon("Connecting", 0);
OnCallConnected();
break;
case eCodecCallStatus.Dialing:
Parent.ShowNotificationRibbon("Connecting", 0);
@@ -350,10 +327,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
DialStringBuilder.Remove(0, DialStringBuilder.Length);
DialStringFeedback.FireUpdate();
Parent.ShowNotificationRibbon("Disconnected", 2000);
Debug.Console(0, "Setting Connect Button mode to 0");
}
break;
case eCodecCallStatus.Disconnecting:
break;
@@ -374,32 +348,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
ShowIncomingModal(call);
break;
}
default:
break;
}
if (meetingInfoSender != null && Codec.IsInCall)
{
var meetingInfo = meetingInfoSender.MeetingInfo;
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue =
(ushort) (meetingInfo.IsSharingMeeting ? 2 : 1);
}
else
{
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue =
(ushort) (Codec.IsInCall ? 1 : 0);
}
uint stageJoin;
if (Codec.IsInCall)
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
else
{
if (Codec is IHasCallHistory)
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithRecentsVisible;
else
stageJoin = UIBoolJoin.VCStagingInactivePopoverWithoutRecentsVisible;
}
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0);
uint stageJoin;
if (Codec.IsInCall)
stageJoin = UIBoolJoin.VCStagingActivePopoverVisible;
else
stageJoin = UIBoolJoin.VCStagingInactivePopoverVisible;
if (IsVisible)
StagingBarsInterlock.ShowInterlocked(stageJoin);
else
@@ -411,36 +369,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
UpdateHeaderActiveCallList();
}
private void OnCallConnected()
{
HidePasswordPrompt();
KeypadMode = eKeypadMode.DTMF;
DialStringBuilder.Remove(0, DialStringBuilder.Length);
DialStringFeedback.FireUpdate();
DialStringTextCheckEnables();
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
ShowKeypad();
UnmuteRoomOnCallConnect();
}
private void UnmuteRoomOnCallConnect()
{
var volControl = Parent.CurrentRoom as IHasCurrentVolumeControls;
if (volControl == null)
{
return;
}
var currentVolControls = volControl.CurrentVolumeControls as IBasicVolumeWithFeedback;
if (currentVolControls != null)
{
currentVolControls.MuteOff();
}
}
/// <summary>
/// Redraws the calls list on the header
/// </summary>
@@ -464,8 +392,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
ActiveCallsSRL.Count = (ushort)activeList.Count;
// If Active Calls list is visible and codec is not in a call, hide the list
if (!Codec.IsInCall && Parent.PopupInterlock.CurrentJoin == Parent.CallListOrMeetingInfoPopoverVisibilityJoin)
Parent.PopupInterlock.ShowInterlockedWithToggle(Parent.CallListOrMeetingInfoPopoverVisibilityJoin);
if (!Codec.IsInCall && Parent.PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible)
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible);
}
/// <summary>
@@ -556,67 +484,20 @@ namespace PepperDash.Essentials.UIDrivers.VC
TriList.SetSigFalseAction(UIBoolJoin.VCStagingRecentsPress, ShowRecents);
TriList.SetSigFalseAction(UIBoolJoin.VCStagingCameraPress, ShowCameraControls);
TriList.SetSigFalseAction(UIBoolJoin.VCStagingConnectPress, ConnectPress);
TriList.SetSigFalseAction(UIBoolJoin.VCStagingMeetNowPress, MeetNowPress);
TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, CallStopSharingPress);
var meetingInfoCodec = Codec as IHasMeetingInfo;
TriList.SetSigFalseAction(UIBoolJoin.CallEndPress, () =>
{
if (Codec.ActiveCalls.Count > 1)
{
Parent.PopupInterlock.ShowInterlocked(Parent.CallListOrMeetingInfoPopoverVisibilityJoin);
}
else if (meetingInfoCodec != null && Codec.ActiveCalls.Count == 1)
{
var meetingInfo = meetingInfoCodec.MeetingInfo;
if (meetingInfo != null && meetingInfo.IsSharingMeeting)
{
var presentationMeetingCodec = Codec as IHasPresentationOnlyMeeting;
if (presentationMeetingCodec != null)
{
presentationMeetingCodec.StartNormalMeetingFromSharingOnlyMeeting();
}
}
else
{
Codec.EndAllCalls();
}
Parent.PopupInterlock.ShowInterlocked(UIBoolJoin.HeaderActiveCallsListVisible);
}
else
{
Codec.EndAllCalls();
}
});
TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, () =>
{
Parent.PopupInterlock.HideAndClear();
Codec.EndAllCalls();
});
if (meetingInfoCodec != null)
{
TriList.SetSigFalseAction(UIBoolJoin.MeetingLeavePress, () =>
{
Parent.PopupInterlock.HideAndClear();
if (meetingInfoCodec.MeetingInfo.IsHost)
{
Codec.EndAllCalls();
}
else
{
var startMeetingCodec = Codec as IHasStartMeeting;
if (startMeetingCodec != null)
{
startMeetingCodec.LeaveMeeting();
}
}
});
}
}
void SetupCameraControls()
@@ -632,21 +513,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
VCControlsInterlock.StatusChanged += new EventHandler<StatusChangedEventArgs>(VCControlsInterlock_StatusChanged);
var codecOffCameras = Codec as IHasCameraOff;
var supportsCameraOffMode = Codec.SupportsCameraOff;
var codecOffCameras = Codec as IHasCameraOff;
var codecAutoCameras = Codec as IHasCameraAutoMode;
var supportsAutoCameraMode = Codec.SupportsCameraAutoMode;
if (codecAutoCameras != null && supportsAutoCameraMode)
if (codecAutoCameras != null)
{
CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn());
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true;
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]);
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCCameraAutoModeIsOnFb]);
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 1 Pressed"].SetSigFalseAction(
//() => codecAutoCameras.CameraAutoModeOn());
@@ -672,7 +548,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
}
};
}
// Manual button always visible
@@ -682,9 +557,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction(
// () => ShowCameraManualMode());
if (codecOffCameras != null && supportsCameraOffMode)
if (codecOffCameras != null)
{
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true;
codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]);
CameraModeList.SetItemButtonAction(3, (b) => codecOffCameras.CameraOff());
@@ -712,7 +586,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
}
};
}
}
@@ -899,14 +772,12 @@ namespace PepperDash.Essentials.UIDrivers.VC
if (camerasCodec != null && camerasCodec.SelectedCamera != null)
{
Debug.Console(2, "Attempting to map camera actions to selected camera: '{0}'", camerasCodec.SelectedCamera.Key);
var dpad = CameraPtzPad;
var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl;
if (camera != null)
{
Debug.Console(2, "Selected camera is IHasCameraPtzControl");
if (camerasCodec.SelectedCamera.CanTilt)
{
dpad.SigUp.SetBoolSigAction((b) =>
@@ -971,46 +842,25 @@ namespace PepperDash.Essentials.UIDrivers.VC
}
}
else
{
Debug.Console(2, "Selected Camera is not IHasCameraPtzControl. No controls to map");
}
}
else
{
Debug.Console(2, "Codec does not have cameras of selected camera is null");
}
}
// Determines if codec is in manual camera control mode and shows feedback
void ShowCameraManualMode()
{
Debug.Console(2, "ShowCameraManualMode");
var inManualMode = true;
var codecOffCameras = Codec as IHasCameraOff;
var codecAutoCameras = Codec as IHasCameraAutoMode;
var supportsAutoCameras = codecAutoCameras != null && Codec.SupportsCameraAutoMode;
if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue)
{
inManualMode = false;
var codecCameraMute = Codec as IHasCameraMute;
if (codecCameraMute != null)
{
codecCameraMute.CameraMuteOff();
inManualMode = true;
}
}
// Clear auto mode
if (supportsAutoCameras)
if (codecAutoCameras != null )
{
if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue)
{
@@ -1101,7 +951,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
// if it's today, show a simpler string
string timeText = null;
if (c.StartTime.Date == DateTime.Now.Date)
timeText = c.StartTime.ToString("t", Global.Culture);
timeText = c.StartTime.ToShortTimeString();
else if (c.StartTime == DateTime.MinValue)
timeText = "";
else
@@ -1158,21 +1008,22 @@ namespace PepperDash.Essentials.UIDrivers.VC
void SetupDirectoryList()
{
var codec = Codec as IHasDirectory;
if (codec == null)
{
return;
}
if (codec != null)
{
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
true, 1300);
codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
true, 1300);
codec.DirectoryResultReturned += dir_DirectoryResultReturned;
if (codec.PhonebookSyncState.InitialSyncComplete)
SetCurrentDirectoryToRoot();
else
{
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
}
if (codec.PhonebookSyncState.InitialSyncComplete)
SetCurrentDirectoryToRoot();
else
{
codec.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
}
RefreshDirectory();
}
}
/// <summary>
@@ -1180,15 +1031,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// </summary>
void SetCurrentDirectoryToRoot()
{
var hasDirectory = Codec as IHasDirectory;
(Codec as IHasDirectory).SetCurrentDirectoryToRoot();
if (hasDirectory == null)
{
return;
}
hasDirectory.SetCurrentDirectoryToRoot();
SearchKeypadClear();
RefreshDirectory();
}
/// <summary>
@@ -1200,17 +1047,10 @@ namespace PepperDash.Essentials.UIDrivers.VC
{
var codec = Codec as IHasDirectory;
if (codec == null)
{
return;
}
if (!codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue)
{
return;
}
SetCurrentDirectoryToRoot();
RefreshDirectory();
}
/// <summary>
@@ -1220,7 +1060,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// <param name="e"></param>
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
{
RefreshDirectory(e.Directory);
RefreshDirectory();
}
/// <summary>
@@ -1249,27 +1090,16 @@ namespace PepperDash.Essentials.UIDrivers.VC
}
/// <summary>
///
/// </summary>
void RefreshDirectory()
/// <summary>
///
/// </summary>
/// <param name="dir"></param>
void RefreshDirectory()
{
var codec = Codec as IHasDirectory;
if (codec == null)
{
return;
}
RefreshDirectory(codec.CurrentDirectoryResult);
}
void RefreshDirectory(CodecDirectory directory)
{
if (directory.CurrentDirectoryResults.Count > 0)
if ((Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults.Count > 0)
{
ushort i = 0;
foreach (var r in directory.CurrentDirectoryResults)
foreach (var r in (Codec as IHasDirectory).CurrentDirectoryResult.CurrentDirectoryResults)
{
if (i == DirectoryList.MaxCount)
{
@@ -1289,33 +1119,19 @@ namespace PepperDash.Essentials.UIDrivers.VC
// If more than one contact method, show contact method modal dialog
DirectoryList.SetItemButtonAction(i, b =>
{
if (b)
if (!b)
{
return;
// Refresh the contact methods list
RefreshContactMethodsModalList(dc);
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
}
// Refresh the contact methods list
RefreshContactMethodsModalList(dc);
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
});
}
else if (dc.ContactMethods.Count == 1)
{
var invitableContact = dc as IInvitableContact;
if (invitableContact != null)
{
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(invitableContact); });
}
else
{
// If only one contact method, just dial that method
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
}
}
else
{
Debug.Console(1, "Unable to dial contact. No availble ContactMethod(s) specified");
// If only one contact method, just dial that method
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
}
}
else // is DirectoryFolder
@@ -1342,7 +1158,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
DirectoryList.SetItemMainText(1, "No Results Found");
}
}
}
void RefreshContactMethodsModalList(DirectoryContact contact)
{
@@ -1387,7 +1204,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
var lc = Codec as IHasCodecLayouts;
if (lc != null)
{
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]);
lc.LocalLayoutFeedback.OutputChange += (o,a) =>
{
@@ -1400,24 +1217,14 @@ namespace PepperDash.Essentials.UIDrivers.VC
var cisco = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.CiscoSparkCodec;
if (cisco != null)
{
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggleSingleProminent);
// Cisco has min/max buttons that need special sauce
cisco.SharingContentIsOnFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
//cisco.PresentationViewMaximizedFeedback.OutputChange += CiscoSharingAndPresentation_OutputChanges;
TriList.SetSigFalseAction(UIBoolJoin.VCMinMaxPress, cisco.MinMaxLayoutToggle);
}
var zoomRoom = Codec as PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom.ZoomRoom;
if (zoomRoom != null)
{
TriList.BooleanInput[UIBoolJoin.VCLayoutToggleEnable].BoolValue = true;
TriList.SetSigFalseAction(UIBoolJoin.VCLayoutTogglePress, lc.LocalLayoutToggle);
}
}
}
/// <summary>
@@ -1445,21 +1252,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
/// </summary>
void RevealKeyboard()
{
if (_passwordPromptDialogVisible)
{
Debug.Console(2, "Attaching Keyboard to PasswordPromptDialog");
DetachDialKeyboard();
DetachSearchKeyboard();
var kb = Parent.Keyboard;
kb.KeyPress -= Keyboard_PasswordKeyPress;
kb.KeyPress += Keyboard_PasswordKeyPress;
kb.HideAction = this.DetachPasswordKeyboard;
kb.GoButtonText = "Submit";
kb.GoButtonVisible = true;
PasswordStringCheckEnables();
kb.Show();
}
else if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial)
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadWithFavoritesVisible && KeypadMode == eKeypadMode.Dial)
{
var kb = Parent.Keyboard;
kb.KeyPress -= Keyboard_DialKeyPress;
@@ -1481,7 +1274,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
SearchStringKeypadCheckEnables();
kb.Show();
}
}
/// <summary>
@@ -1537,32 +1329,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
}
}
/// <summary>
/// Event handler for keyboard dialing
/// </summary>
void Keyboard_PasswordKeyPress(object sender, PepperDash.Essentials.Core.Touchpanels.Keyboards.KeyboardControllerPressEventArgs e)
{
if (_passwordPromptDialogVisible)
{
if (e.Text != null)
PasswordStringBuilder.Append(e.Text);
else
{
if (e.SpecialKey == KeyboardSpecialKey.Backspace)
PasswordKeypadBackspacePress();
else if (e.SpecialKey == KeyboardSpecialKey.Clear)
PasswordKeypadClear();
else if (e.SpecialKey == KeyboardSpecialKey.GoButton)
{
(Codec as IPasswordPrompt).SubmitPassword(PasswordStringBuilder.ToString());
HidePasswordPrompt();
}
}
PasswordStringFeedback.FireUpdate();
PasswordStringCheckEnables();
}
}
/// <summary>
/// Call
/// </summary>
@@ -1576,11 +1342,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
Parent.Keyboard.KeyPress -= Keyboard_SearchKeyPress;
}
void DetachPasswordKeyboard()
{
Parent.Keyboard.KeyPress -= Keyboard_PasswordKeyPress;
}
/// <summary>
/// Shows the camera controls subpage
/// </summary>
@@ -1658,22 +1419,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingRecentsPress);
}
/// <summary>
/// Meet Now button
/// </summary>
void MeetNowPress()
{
var startMeetingCodec = Codec as IHasStartMeeting;
if (startMeetingCodec != null)
{
startMeetingCodec.StartMeeting(startMeetingCodec.DefaultMeetingDurationMin);
}
else
{
Debug.Console(2, "Codce does not implment IHasStartMeeting. Cannot meet now");
}
}
/// <summary>
/// Connect call button
/// </summary>
@@ -1684,16 +1429,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
Codec.Dial(DialStringBuilder.ToString());
}
/// <summary>
/// Stop Sharing button
/// </summary>
void CallStopSharingPress()
{
Codec.StopSharing();
Parent.CurrentRoom.RunRouteAction("codecOsd", Parent.CurrentRoom.SourceListKey);
}
/// <summary>
///
/// </summary>
@@ -1860,40 +1595,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
Parent.Keyboard.DisableGoButton();
}
/// <summary>
/// Clears the Password keypad
/// </summary>
void PasswordKeypadClear()
{
PasswordStringBuilder.Remove(0, PasswordStringBuilder.Length);
PasswordStringFeedback.FireUpdate();
PasswordStringCheckEnables();
}
/// <summary>
///
/// </summary>
void PasswordKeypadBackspacePress()
{
PasswordStringBuilder.Remove(PasswordStringBuilder.Length - 1, 1);
PasswordStringFeedback.FireUpdate();
PasswordStringCheckEnables();
}
/// <summary>
/// Checks the enabled states of various elements around the keypad
/// </summary>
void PasswordStringCheckEnables()
{
var textIsEntered = PasswordStringBuilder.Length > 0;
if (textIsEntered)
Parent.Keyboard.EnableGoButton();
else
Parent.Keyboard.DisableGoButton();
}
/// <summary>
/// Returns the text value for the keypad dial entry field
@@ -1939,62 +1640,5 @@ namespace PepperDash.Essentials.UIDrivers.VC
Dial = 0,
DTMF
}
void SetupPasswordPrompt()
{
var passwordPromptCodec = Codec as IPasswordPrompt;
passwordPromptCodec.PasswordRequired += new EventHandler<PasswordPromptEventArgs>(passwordPromptCodec_PasswordRequired);
TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptCancelPress, HidePasswordPrompt);
TriList.SetSigFalseAction(UIBoolJoin.PasswordPromptTextPress, RevealKeyboard);
}
void passwordPromptCodec_PasswordRequired(object sender, PasswordPromptEventArgs e)
{
if (e.LoginAttemptCancelled)
{
HidePasswordPrompt();
return;
}
if (!string.IsNullOrEmpty(e.Message))
{
TriList.SetString(UIStringJoin.PasswordPromptMessageText, e.Message);
}
if (e.LoginAttemptFailed)
{
// TODO: Show a message modal to indicate the login attempt failed
return;
}
TriList.SetBool(UIBoolJoin.PasswordPromptErrorVisible, e.LastAttemptWasIncorrect);
ShowPasswordPrompt();
}
private bool _passwordPromptDialogVisible;
void ShowPasswordPrompt()
{
// Clear out any previous data
PasswordKeypadClear();
_passwordPromptDialogVisible = true;
TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible);
RevealKeyboard();
}
void HidePasswordPrompt()
{
if (_passwordPromptDialogVisible)
{
_passwordPromptDialogVisible = false;
Parent.Keyboard.Hide();
TriList.SetBool(UIBoolJoin.PasswordPromptDialogVisible, _passwordPromptDialogVisible);
PasswordKeypadClear();
}
}
}
}

View File

@@ -54,10 +54,6 @@ Utilization of Essentials Framework falls into the following categories:
For detailed documentation, see the [Wiki](https://github.com/PepperDash/EssentialsFramework/wiki).
## Support
* Check out our [Discord Server](https://discord.gg/rWyeRH3K)
## How-To (Getting Started)
See [Getting Started](https://github.com/PepperDash/Essentials/wiki/Get-started#how-to-get-started)

View File

@@ -42,6 +42,3 @@ devjson:2 {"deviceKey":"display01Comm-com", "methodName":"SendText", "params": [
devjson:10 {"deviceKey":"dmLink-ssh", "methodName":"Connect", "params": []}
devjson:2 {"deviceKey":"roomCombiner", "methodName":"SetRoomCombinationScenario", "params": ["combined"]}
devjson:2 {"deviceKey":"roomCombiner", "methodName":"SetRoomCombinationScenario", "params": ["divided"]}

View File

@@ -46,33 +46,6 @@ namespace PepperDash.Essentials.Core.Bridges
bridge.PrintJoinMaps();
}
}
public static void JoinmapMarkdown(string command)
{
var targets = command.Split(' ');
var bridgeKey = targets[0].Trim();
var bridge = DeviceManager.GetDeviceForKey(bridgeKey) as EiscApiAdvanced;
if (bridge == null)
{
Debug.Console(0, "Unable to find advanced bridge with key: '{0}'", bridgeKey);
return;
}
if (targets.Length > 1)
{
var deviceKey = targets[1].Trim();
if (string.IsNullOrEmpty(deviceKey)) return;
bridge.MarkdownJoinMapForDevice(deviceKey, bridgeKey);
}
else
{
bridge.MarkdownForBridge(bridgeKey);
}
}
}
@@ -105,11 +78,11 @@ namespace PepperDash.Essentials.Core.Bridges
/// <summary>
/// Bridge API using EISC
/// </summary>
public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
public class EiscApiAdvanced : BridgeApi
{
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
public Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
protected Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
public BasicTriList Eisc { get; private set; }
@@ -125,35 +98,13 @@ 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);
@@ -165,7 +116,7 @@ namespace PepperDash.Essentials.Core.Bridges
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
if (!typeof(IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
@@ -179,14 +130,6 @@ namespace PepperDash.Essentials.Core.Bridges
bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
}
}
}
private void RegisterEisc()
{
if (Eisc.Registered)
{
return;
}
var registerResult = Eisc.Register();
@@ -199,31 +142,6 @@ 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>
@@ -254,19 +172,6 @@ namespace PepperDash.Essentials.Core.Bridges
joinMap.Value.PrintJoinMapInfo();
}
}
/// <summary>
/// Generates markdown for all join maps on this bridge
/// </summary>
public virtual void MarkdownForBridge(string bridgeKey)
{
Debug.Console(0, this, "Writing Joinmaps to files for EISC IPID: {0}", Eisc.ID.ToString("X"));
foreach (var joinMap in JoinMaps)
{
Debug.Console(0, "Generating markdown for device '{0}':", joinMap.Key);
joinMap.Value.MarkdownJoinMapInfo(joinMap.Key, bridgeKey);
}
}
/// <summary>
/// Prints the join map for a device by key
@@ -282,26 +187,9 @@ namespace PepperDash.Essentials.Core.Bridges
return;
}
Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
joinMap.PrintJoinMapInfo();
}
/// <summary>
/// Prints the join map for a device by key
/// </summary>
/// <param name="deviceKey"></param>
public void MarkdownJoinMapForDevice(string deviceKey, string bridgeKey)
{
var joinMap = JoinMaps[deviceKey];
if (joinMap == null)
{
Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
return;
}
Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
joinMap.MarkdownJoinMapInfo(deviceKey, bridgeKey);
}
/// <summary>
/// Used for debugging to trigger an action based on a join number and type
@@ -392,12 +280,6 @@ 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
@@ -408,9 +290,6 @@ namespace PepperDash.Essentials.Core.Bridges
[JsonProperty("devices")]
public List<ApiDevicePropertiesConfig> Devices { get; set; }
[JsonProperty("rooms")]
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
public class ApiDevicePropertiesConfig
{
@@ -424,25 +303,13 @@ 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>
{
public EiscApiAdvancedFactory()
{
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "vceiscapiadv", "vceiscapiadvanced" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -451,51 +318,25 @@ namespace PepperDash.Essentials.Core.Bridges
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
BasicTriList eisc;
switch (dc.Type.ToLower())
{
case "eiscapiadv":
case "eiscapiadvanced":
{
eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
break;
}
case "eiscapiadvancedserver":
{
eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
break;
}
case "eiscapiadvancedclient":
{
eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
break;
}
{
var eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
}
case "vceiscapiadv":
case "vceiscapiadvanced":
{
if (string.IsNullOrEmpty(controlProperties.RoomId))
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to build VC-4 EISC Client for device {0}. Room ID is missing or empty", dc.Key);
eisc = null;
break;
}
eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, controlProperties.RoomId,
Global.ControlSystem);
break;
}
{
var eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, InitialParametersClass.RoomId,
Global.ControlSystem);
return new EiscApiAdvanced(dc, eisc);
}
default:
eisc = null;
break;
return null;
}
if (eisc == null)
{
return null;
}
return new EiscApiAdvanced(dc, eisc);
}
}

View File

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

View File

@@ -46,14 +46,6 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete RawOccupancyUsFeedback = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 },
new JoinMetadata { Description = "Raw Occupancy Us Feedback", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("IdentityModeOn")]
public JoinDataComplete IdentityMode = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
new JoinMetadata { Description = "Enable Identity Mode", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("IdentityModeFeedback")]
public JoinDataComplete IdentityModeFeedback = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
new JoinMetadata { Description = "Identity Mode Feedback", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("EnableLedFlash")]
public JoinDataComplete EnableLedFlash = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Enable Led Flash", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });

View File

@@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinMetadata
{
Description = "DM Chassis enable audio breakaway routing",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
@@ -20,14 +20,10 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinMetadata
{
Description = "DM Chassis enable USB breakaway routing",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("SystemId")]
public JoinDataComplete SystemId = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis SystemId Get/Set/Trigger/", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalog });
@@ -80,18 +76,6 @@ 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("NoRouteName")]
public JoinDataComplete NoRouteName = new JoinDataComplete(new JoinData { JoinNumber = 100, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[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 });
@@ -104,7 +88,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinDataComplete(new JoinData {JoinNumber = 501, JoinSpan = 200},
new JoinMetadata
{
Description = "DM Chassis Video Input Names",
Description = "Video Input Name",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
@@ -114,7 +98,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinDataComplete(new JoinData { JoinNumber = 701, JoinSpan = 200 },
new JoinMetadata
{
Description = "DM Chassis Audio Input Names",
Description = "Video Input Name",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
@@ -123,7 +107,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinDataComplete(new JoinData { JoinNumber = 901, JoinSpan = 200 },
new JoinMetadata
{
Description = "DM Chassis Video Output Names",
Description = "Video Input Name",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});
@@ -132,7 +116,7 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinDataComplete(new JoinData { JoinNumber = 1101, JoinSpan = 200 },
new JoinMetadata
{
Description = "DM Chassis Audio Output Names",
Description = "Video Input Name",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Serial
});

View File

@@ -28,36 +28,10 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete EdidSerialNumber = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC EDID Serial Number", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("AudioVideoSource")]
public JoinDataComplete AudioVideoSource = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC Audio Video Source Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("HdcpSupportCapability")]
public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC HDCP Support Capability", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("Port1HdcpState")]
public JoinDataComplete Port1HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC Port 1 (DM) HDCP State Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Port2HdcpState")]
public JoinDataComplete Port2HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Port 2 (HDMI) HDCP State Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("HdmiInputSync")]
public JoinDataComplete HdmiInputSync = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC HDMI Input Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("HdcpInputPortCount")]
public JoinDataComplete HdcpInputPortCount = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
new JoinMetadata { Description = "Number of Input Ports that support HDCP", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
@@ -72,8 +46,7 @@ namespace PepperDash.Essentials.Core.Bridges
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
/// <param name="type">Type of the child join map</param>
protected DmRmcControllerJoinMap(uint joinStart, Type type)
: base(joinStart, type)
protected DmRmcControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
{
}
}

View File

@@ -32,10 +32,6 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete CurrentInputResolution = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Current Input Resolution", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("VideoInput")]
public JoinDataComplete VideoInput = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Video Input Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
@@ -46,7 +42,7 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("HdcpSupportCapability")]
public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX HDCP Support Capability", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
new JoinMetadata { Description = "DM TX HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Port1HdcpState")]
public JoinDataComplete Port1HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
@@ -64,16 +60,6 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete VgaContrast = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Online", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Port3HdcpState")]
public JoinDataComplete Port3HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Port 3 HDCP State Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("HdcpInputPortCount")]
public JoinDataComplete HdcpInputPortCount = new JoinDataComplete(new JoinData { JoinNumber = 9, JoinSpan = 1 },
new JoinMetadata { Description = "Number of Input Ports that support HDCP", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
@@ -88,8 +74,7 @@ namespace PepperDash.Essentials.Core.Bridges
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
/// <param name="type">Type of the child join map</param>
protected DmTxControllerJoinMap(uint joinStart, Type type)
: base(joinStart, type)
protected DmTxControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
{
}
}

View File

@@ -7,19 +7,7 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("MasterVolumeLevel")]
public JoinDataComplete MasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MasterVolumeLevelScaled")]
public JoinDataComplete MasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MixerPresetRecall")]
public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MixerEqPresetRecall")]
public JoinDataComplete MixerEqPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Eq Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
new JoinMetadata { Description = "Master Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MasterVolumeMuteOn")]
public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
@@ -35,19 +23,11 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("MasterVolumeDown")]
public JoinDataComplete MasterVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MasterVolumeLevelScaledSend")]
public JoinDataComplete MasterVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
new JoinMetadata { Description = "Master Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SourceVolumeLevel")]
public JoinDataComplete SourceVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Source Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("SourceVolumeLevelScaled")]
public JoinDataComplete SourceVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "Source Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
new JoinMetadata { Description = "Source Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("SourceVolumeMuteOn")]
public JoinDataComplete SourceVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
@@ -63,19 +43,11 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("SourceVolumeDown")]
public JoinDataComplete SourceVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
new JoinMetadata { Description = "Source Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SourceVolumeLevelScaledSend")]
public JoinDataComplete SourceVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 },
new JoinMetadata { Description = "Source Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
new JoinMetadata { Description = "Source Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("Codec1VolumeLevel")]
public JoinDataComplete Codec1VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 },
new JoinMetadata { Description = "Codec1 Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Codec1VolumeLevelScaled")]
public JoinDataComplete Codec1VolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 },
new JoinMetadata { Description = "Codec1 Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
new JoinMetadata { Description = "Codec1 Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Codec1VolumeMuteOn")]
public JoinDataComplete Codec1VolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 },
@@ -91,19 +63,11 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("Codec1VolumeDown")]
public JoinDataComplete Codec1VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 },
new JoinMetadata { Description = "Codec1 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("Codec1VolumeLevelScaledSend")]
public JoinDataComplete Codec1VolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 25, JoinSpan = 1 },
new JoinMetadata { Description = "Codec1 Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
new JoinMetadata { Description = "Codec1 Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("Codec2VolumeLevel")]
public JoinDataComplete Codec2VolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 },
new JoinMetadata { Description = "Codec2 Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Codec2VolumeLevelScaled")]
public JoinDataComplete Codec2VolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 32, JoinSpan = 1 },
new JoinMetadata { Description = "Codec2 Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
new JoinMetadata { Description = "Codec2 Volume Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("Codec2VolumeMuteOn")]
public JoinDataComplete Codec2VolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 },
@@ -119,39 +83,8 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("Codec2VolumeDown")]
public JoinDataComplete Codec2VolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 },
new JoinMetadata { Description = "Codec2 Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
new JoinMetadata { Description = "Codec2 Volume Mute Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("Codec2VolumeLevelScaledSend")]
public JoinDataComplete Codec2VolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 35, JoinSpan = 1 },
new JoinMetadata { Description = "Codec2 Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicsMasterVolumeLevel")]
public JoinDataComplete MicsMasterVolumeLevel = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 },
new JoinMetadata { Description = "MicsMaster Volume Signed dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MicsMasterVolumeLevelScaled")]
public JoinDataComplete MicsMasterVolumeLevelScaled = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
new JoinMetadata { Description = "MicsMaster Volume 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MicsMasterVolumeMuteOn")]
public JoinDataComplete MicsMasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 },
new JoinMetadata { Description = "MicsMaster Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicsMasterVolumeMuteOff")]
public JoinDataComplete MicsMasterVolumeMuteOff = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
new JoinMetadata { Description = "MicsMaster Volume Mute Off Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicsMasterVolumeUp")]
public JoinDataComplete MicsMasterVolumeUp = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 },
new JoinMetadata { Description = "MicsMaster Volume Level Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicsMasterVolumeDown")]
public JoinDataComplete MicsMasterVolumeDown = new JoinDataComplete(new JoinData { JoinNumber = 44, JoinSpan = 1 },
new JoinMetadata { Description = "MicsMaster Volume Level Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicsMasterVolumeLevelScaledSend")]
public JoinDataComplete MicsMasterVolumeLevelScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 45, JoinSpan = 1 },
new JoinMetadata { Description = "Mics Master Volume Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it

View File

@@ -1,50 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class DmpsMicrophoneControllerJoinMap : JoinMapBaseAdvanced
{
[JoinName("MicGain")]
public JoinDataComplete MicGain = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Mic Gain dB Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MicGainScaled")]
public JoinDataComplete MicGainScaled = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "Mic Gain 16bit Scaled Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MicMuteOn")]
public JoinDataComplete MicMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Mic Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicMuteOff")]
public JoinDataComplete MicMuteOff = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "Mic Mute Off Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicGainScaledSend")]
public JoinDataComplete MicGainScaledSend = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "Mic Gain Scaled Send Enable/Disable", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("MicName")]
public JoinDataComplete MicName = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Mic Name Get", 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 DmpsMicrophoneControllerJoinMap(uint joinStart)
: this(joinStart, typeof(DmpsMicrophoneControllerJoinMap))
{
}
/// <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 DmpsMicrophoneControllerJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -1,29 +1,9 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced
{
[JoinName("EnableRouting")]
public JoinDataComplete EnableRouting = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS Enable Audio and Video Routing", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SystemPowerOn")]
public JoinDataComplete SystemPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS System Power On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("SystemPowerOff")]
public JoinDataComplete SystemPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS System Power Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("FrontPanelLockOn")]
public JoinDataComplete FrontPanelLockOn = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS Front Panel Lock On Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("FrontPanelLockOff")]
public JoinDataComplete FrontPanelLockOff = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 },
new JoinMetadata { Description = "DMPS Front Panel Lock Off Get/Set", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
namespace PepperDash.Essentials.Core.Bridges
{
public class DmpsRoutingControllerJoinMap : JoinMapBaseAdvanced
{
[JoinName("VideoSyncStatus")]
public JoinDataComplete VideoSyncStatus = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
new JoinMetadata { Description = "DM Input Video Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
@@ -52,44 +32,6 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete OutputNames = new JoinDataComplete(new JoinData { JoinNumber = 301, JoinSpan = 32 },
new JoinMetadata { Description = "DM Chassis Output Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("InputVideoNames")]
public JoinDataComplete InputVideoNames =
new JoinDataComplete(new JoinData { JoinNumber = 501, JoinSpan = 32 },
new JoinMetadata
{
Description = "Video Input Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("InputAudioNames")]
public JoinDataComplete InputAudioNames =
new JoinDataComplete(new JoinData { JoinNumber = 701, JoinSpan = 32 },
new JoinMetadata
{
Description = "Audio Input Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("OutputVideoNames")]
public JoinDataComplete OutputVideoNames =
new JoinDataComplete(new JoinData { JoinNumber = 901, JoinSpan = 32 },
new JoinMetadata
{
Description = "Video Output Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("OutputAudioNames")]
public JoinDataComplete OutputAudioNames =
new JoinDataComplete(new JoinData { JoinNumber = 1101, JoinSpan = 32 },
new JoinMetadata
{
Description = "Audio Output Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("OutputCurrentVideoInputNames")]
public JoinDataComplete OutputCurrentVideoInputNames = new JoinDataComplete(new JoinData { JoinNumber = 2001, JoinSpan = 32 },
new JoinMetadata { Description = "DM Chassis Video Output Currently Routed Video Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
@@ -119,5 +61,5 @@ namespace PepperDash.Essentials.Core.Bridges
protected DmpsRoutingControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
{
}
}
}
}

View File

@@ -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 PIR Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
new JoinMetadata { Description = "Occ Sensor Ultrasonic Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },

View File

@@ -3,288 +3,129 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
{
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
{
#region Digital
[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("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
});
#endregion
#region 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
});
#endregion
#region 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
});
#endregion
/// <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
/// </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
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("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

View File

@@ -1,34 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class IAnalogInputJoinMap : JoinMapBaseAdvanced
{
[JoinName("InputValue")]
public JoinDataComplete InputValue = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Input Value", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("MinimumChange")]
public JoinDataComplete MinimumChange = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "Minimum voltage change required to reflect a change", 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 IAnalogInputJoinMap(uint joinStart)
: this(joinStart, typeof(IAnalogInputJoinMap))
{
}
/// <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 IAnalogInputJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -1,13 +1,13 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class IDigitalInputJoinMap : JoinMapBaseAdvanced
{
namespace PepperDash.Essentials.Core.Bridges
{
public class IDigitalInputJoinMap : JoinMapBaseAdvanced
{
[JoinName("InputState")]
public JoinDataComplete InputState = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Input State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
new JoinMetadata { Description = "Room Email Url", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
@@ -26,6 +26,6 @@ namespace PepperDash.Essentials.Core.Bridges
protected IDigitalInputJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}
}
}

View File

@@ -1,31 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class IDigitalOutputJoinMap : JoinMapBaseAdvanced
{
[JoinName("OutputState")]
public JoinDataComplete OutputState = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Get / Set state of Digital Input", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, 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 IDigitalOutputJoinMap(uint joinStart)
: this(joinStart, typeof(IDigitalOutputJoinMap))
{
}
/// <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 IDigitalOutputJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -1,222 +0,0 @@
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)
{
}
}
}

View File

@@ -1,60 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class PduJoinMapBase : JoinMapBaseAdvanced
{
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("Online")]
public JoinDataComplete Online = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletCount")]
public JoinDataComplete OutletCount = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Number of COntrolled Outlets", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("OutletName")]
public JoinDataComplete OutletName = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("OutletEnabled")]
public JoinDataComplete OutletEnabled = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Enabled", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerCycle")]
public JoinDataComplete OutletPowerCycle = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Cycle", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOn")]
public JoinDataComplete OutletPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOff")]
public JoinDataComplete OutletPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, 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 PduJoinMapBase(uint joinStart)
:base(joinStart, typeof(PduJoinMapBase))
{
}
/// <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 PduJoinMapBase(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

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

View File

@@ -45,9 +45,9 @@ namespace PepperDash.Essentials.Core.Bridges
new JoinMetadata { Description = "Processor Last Boot", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("ProgramOffsetJoin")]
public JoinDataComplete ProgramOffsetJoin = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 5 },
public JoinDataComplete ProgramOffsetJoin = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
new JoinMetadata { Description = "All Program Data is offset between slots by 5 - First Joins Start at 11", JoinCapabilities = eJoinCapabilities.None, JoinType = eJoinType.None });
[JoinName("ProgramStart")]
public JoinDataComplete ProgramStart = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Processor Program Start / Fb", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
@@ -132,23 +132,6 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete DhcpStatus = new JoinDataComplete(new JoinData { JoinNumber = 86, JoinSpan = 1 },
new JoinMetadata { Description = "Processor Ethernet Dhcp Status", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("ProcessorRebot")]
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Reboot processor", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
[JoinName("IsAppliance")]
public JoinDataComplete IsAppliance = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Is appliance Fb", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("IsServer")]
public JoinDataComplete IsServer = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
new JoinMetadata { Description = "Is server Fb", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("ProgramReset")]
public JoinDataComplete ProgramReset = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 },
new JoinMetadata { Description = "Resets the program", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>

View File

@@ -11,10 +11,8 @@ using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class CecPortController : Device, IBasicCommunicationWithStreamDebugging
public class CecPortController : Device, IBasicCommunication
{
public CommunicationStreamDebugging StreamDebugging { get; private set; }
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
@@ -25,8 +23,6 @@ namespace PepperDash.Essentials.Core
public CecPortController(string key, Func<EssentialsControlPropertiesConfig, ICec> postActivationFunc,
EssentialsControlPropertiesConfig config):base(key)
{
StreamDebugging = new CommunicationStreamDebugging(key);
AddPostActivationAction(() =>
{
Port = postActivationFunc(config);
@@ -54,21 +50,15 @@ namespace PepperDash.Essentials.Core
void OnDataReceived(string s)
{
var bytesHandler = BytesReceived;
var bytesHandler = BytesReceived;
if (bytesHandler != null)
{
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
if (StreamDebugging.RxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived;
if (textHandler != null)
{
if (StreamDebugging.RxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Received: '{0}'", s);
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
}
if (textHandler != null)
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
}
#region IBasicCommunication Members
@@ -77,8 +67,6 @@ namespace PepperDash.Essentials.Core
{
if (Port == null)
return;
if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text);
Port.StreamCec.Send.StringValue = text;
}
@@ -87,8 +75,6 @@ namespace PepperDash.Essentials.Core
if (Port == null)
return;
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
if (StreamDebugging.TxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
Port.StreamCec.Send.StringValue = text;
}

View File

@@ -56,11 +56,6 @@ 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();
@@ -92,20 +87,18 @@ namespace PepperDash.Essentials.Core
void OnDataReceived(string s)
{
var bytesHandler = BytesReceived;
if (bytesHandler != null)
{
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
if (StreamDebugging.RxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
}
var textHandler = TextReceived;
if (textHandler != null)
{
if (StreamDebugging.RxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Received: '{0}'", s);
if (StreamDebugging.RxStreamDebuggingIsEnabled)
Debug.Console(0, this, "Recevied: '{0}'", s);
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
}
}

View File

@@ -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,Debug.ErrorLogLevel.Notice, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
return null;
}
@@ -183,8 +183,6 @@ namespace PepperDash.Essentials.Core
[JsonConverter(typeof(ComSpecJsonConverter))]
public ComPort.ComPortSpec ComParams { get; set; }
public string RoomId { get; set; }
public string CresnetId { get; set; }
/// <summary>

View File

@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
{
Communication = comm;
PortGather = new CommunicationGather(Communication, '\x0d');
//PortGather.LineReceived += this.Port_LineReceived;
PortGather.LineReceived += this.Port_LineReceived;
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
LineEnding = props.LineEnding;
}
@@ -47,6 +47,13 @@ namespace PepperDash.Essentials.Core
return true;
}
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
{
if (Debug.Level == 2)
Debug.Console(2, this, "RX: '{0}'",
ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text);
}
void SendLine(string s)
{
//if (Debug.Level == 2)

View File

@@ -25,7 +25,6 @@ namespace PepperDash.Essentials.Core
public GenericComm(DeviceConfig config)
: base(config)
{
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
var commPort = CommFactory.CreateCommForDevice(config);
@@ -97,6 +96,7 @@ namespace PepperDash.Essentials.Core
// this is a permanent event handler. This cannot be -= from event
CommPort.TextReceived += (s, a) =>
{
Debug.Console(2, this, "RX: {0}", a.Text);
trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text);
};
trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s));

View File

@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Net.Http;
using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Core.DebugThings;
namespace PepperDash.Essentials.Core
{
@@ -16,130 +17,59 @@ namespace PepperDash.Essentials.Core
public GenericHttpClient(string key, string name, string hostname)
: base(key, name)
{
Client = new HttpClient {HostName = hostname};
Client = new HttpClient();
Client.HostName = hostname;
}
public GenericHttpClient(string key, string name, string hostname, GenericHttpClientConnectionOptions options)
: base(key, name)
{
Client = new HttpClient
{
HostName = hostname,
Accept = options.Accept,
KeepAlive = options.KeepAlive,
Password = options.Password,
Timeout = options.Timeout,
TimeoutEnabled = options.TimeoutEnabled,
UserAgent = options.UserAgent,
UserName = options.UserName,
Version = options.Version
};
if (options.Port > 0) Client.Port = options.Port;
}
/// <summary>
/// Send a HTTP Get Request to a client
/// <summary>
///
/// </summary>
/// <param name="path">Path to request node</param>
public void SendText(string path)
{
var url = string.Format("http://{0}/{1}", Client.HostName, path);
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <param name="path"></param>
public void SendText(string path)
{
HttpClientRequest request = new HttpClientRequest();
string url = string.Format("http://{0}/{1}", Client.HostName, path);
request.Url = new UrlParser(url);
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
}
public void SendText(string format, params object[] items)
{
HttpClientRequest request = new HttpClientRequest();
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
request.Url = new UrlParser(url);
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
}
/// <summary>
/// Send a HTTP Get Request to a client using a formatted string
/// </summary>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendText(string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send a unidirectional HTTP Get Request to a client using a formatted string
/// </summary>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendTextNoResponse(string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
Client.Dispatch(request);
}
/// <summary>
/// Send an HTTP Request of a specific request type
/// </summary>
/// <param name="requestType">HTTP Request Type</param>
/// <param name="path">Path to request node</param>
public void SendText(RequestType requestType, string path)
{
var url = string.Format("http://{0}/{1}", Client.HostName, path);
var request = new HttpClientRequest()
{
Url = new UrlParser(url),
RequestType = requestType
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send an HTTP Request of a specific request type using a formatted string
/// </summary>
/// <param name="requestType">HTTP Request Type</param>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendText(RequestType requestType, string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url),
RequestType = requestType
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send a unidirectional HTTP Request of a specific request type using a formatted string
/// </summary>
/// <param name="requestType">HTTP Request Type</param>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendTextNoResponse(RequestType requestType, string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
Client.Dispatch(request);
}
public void SendTextNoResponse(string format, params object[] items)
{
HttpClientRequest request = new HttpClientRequest();
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
request.Url = new UrlParser(url);
Client.Dispatch(request);
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
}
private void Response(HttpClientResponse response, HTTP_CALLBACK_ERROR error, object request)
{
if (error != HTTP_CALLBACK_ERROR.COMPLETED) return;
var responseReceived = response;
if (error == HTTP_CALLBACK_ERROR.COMPLETED)
{
var responseReceived = response;
if (responseReceived.ContentString.Length > 0)
{
if (ResponseRecived != null)
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error));
Debug.Console(2, this, "GenericHttpClient ResponseReceived");
Debug.Console(2, this, "RX:{0}", responseReceived.ContentString);
Debug.Console(2, this, "TX:{0}", (request as HttpClientRequest).Url.ToString());
}
}
if (responseReceived.ContentString.Length <= 0) return;
if (ResponseRecived == null) return;
var httpClientRequest = request as HttpClientRequest;
if (httpClientRequest != null)
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, httpClientRequest.Url.ToString(), error));
}
@@ -177,8 +107,6 @@ namespace PepperDash.Essentials.Core
#endregion
}
public class GenericHttpClientEventArgs : EventArgs
{
public string ResponseText { get; private set; }
@@ -191,84 +119,4 @@ namespace PepperDash.Essentials.Core
Error = error;
}
}
/// <summary>
/// Objedct to set parameters for HTTP Requests
/// </summary>
public class GenericHttpClientConnectionOptions
{
/// <summary>
/// Gets or sets content types that are acceptable for the response. The default
/// value is "text/html, image/gif, image/jpeg, image/png, */*".
/// </summary>
[DefaultValue("text/html, image/gif, image/jpeg, image/png")]
public string Accept { get; set; }
/// <summary>
/// Controls whether to use HTTP Keep-Alive to keep the connection alive between
/// requests. If enabled (true) , once a request is made and a connection is
/// established, this connection is kept open and used for future requests. If
/// disabled, the connection is closed, and a new connection is created for future
/// requests.
/// </summary>
[DefaultValue(true)]
public bool KeepAlive { get; set; }
/// <summary>
/// This property controls whether the request operation will do an automatic
/// timeout checking. If timeout handling is turned on (i.e. this property is
/// set to true) and a request takes longer than Timeout, it will be terminated.
/// </summary>
[DefaultValue(true)]
public bool TimeoutEnabled { get; set; }
/// <summary>
/// Gets or sets the maximum amount of time (in seconds) that a client will wait
/// for a server response within a single request. The default value is 60 seconds
/// (1 minute). The timeout handling can be activated via the TimeoutEnabled
/// property.
/// </summary>
[DefaultValue(60)]
public int Timeout { get; set; }
/// <summary>
/// Gets or sets the version identifier of the UserAgent. Can be used to mimic
/// particular browsers like Internet Explorer 6.0
/// </summary>
[DefaultValue("1.1")]
public string Version { get; set; }
/// <summary>
/// Gets or sets the identifier of the software being used to retrieve data via
/// the URL. Some custom HTTP servers check this HTTP header to provide content
/// optimized for particular HTTP browsers.
/// </summary>
[DefaultValue("Crestron SimplSharp HTTP Client")]
public string UserAgent { get; set; }
/// <summary>
/// Name that will be inserted into the Authorization HTTP header in the request
/// to the server.
/// </summary>
public string UserName { get; set; }
/// <summary>
/// Password that will be inserted into the Authorization HTTP header in the
/// request to the server.
/// </summary>
public string Password { get; set; }
/// <summary>
/// The server Port that you intend the client to connect to. If you do not
/// assign a port number on this property, the port number in the parsed URL
/// will be used. If a port number is assigned in the parsed URL, it will take
/// precedence over this property.
/// </summary>
/// <remarks>
/// If you do not assign a port number on this property, the port number in the
/// parsed URL will be used.
/// </remarks>
///
public int Port { get; set; }
}
}

View File

@@ -1,8 +1,12 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
namespace PepperDash.Essentials.Core.Config
{
@@ -21,23 +25,13 @@ namespace PepperDash.Essentials.Core.Config
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
[JsonProperty("destinationLists")]
public Dictionary<string, Dictionary<string,DestinationListItem>> DestinationLists { get; set; }
public Dictionary<string, Dictionary<string, DestinationListItem>> DestinationLists { get; set; }
[JsonProperty("tieLines")]
public List<TieLineConfig> TieLines { get; set; }
[JsonProperty("joinMaps")]
public Dictionary<string, JObject> JoinMaps { get; set; }
public BasicConfig()
{
Info = new InfoConfig();
Devices = new List<DeviceConfig>();
SourceLists = new Dictionary<string, Dictionary<string, SourceListItem>>();
DestinationLists = new Dictionary<string, Dictionary<string, DestinationListItem>>();
TieLines = new List<TieLineConfig>();
JoinMaps = new Dictionary<string, JObject>();
}
public Dictionary<string, string> JoinMaps { get; set; }
/// <summary>
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
@@ -50,20 +44,13 @@ namespace PepperDash.Essentials.Core.Config
return SourceLists[key];
}
/// <summary>
/// Retrieves a DestinationListItem based on the key
/// </summary>
/// <param name="key">key of the item to retrieve</param>
/// <returns>DestinationListItem if the key exists, null otherwise</returns>
public Dictionary<string, DestinationListItem> GetDestinationListForKey(string key)
{
if (string.IsNullOrEmpty(key) || !DestinationLists.ContainsKey(key))
{
if (string.IsNullOrEmpty(key) || !SourceLists.ContainsKey(key))
return null;
}
return DestinationLists[key];
}
}
/// <summary>
/// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null
@@ -77,12 +64,9 @@ namespace PepperDash.Essentials.Core.Config
var deviceConfig = Devices.FirstOrDefault(d => d.Key.Equals(key));
if (deviceConfig != null)
return deviceConfig;
else
{
return null;
}
//removed if statement that was here...
//DeviceConfig will be null if it's not found in the list
return deviceConfig;
}
}
}

View File

@@ -1,80 +1,65 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
public class DeviceConfig
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("uid")]
public int Uid { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; }
public DeviceConfig(DeviceConfig dc)
{
Key = dc.Key;
Uid = dc.Uid;
Name = dc.Name;
Group = dc.Group;
Type = dc.Type;
Properties = JToken.Parse(dc.Properties.ToString());
//Properties = JToken.FromObject(dc.Properties);
}
public DeviceConfig() {}
}
/// <summary>
///
/// </summary>
public class DevicePropertiesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(JToken);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JToken.ReadFrom(reader);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("SOD OFF HOSER");
}
}
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Config
{
public class DeviceConfig
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("uid")]
public int Uid { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("group")]
public string Group { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("properties")]
[JsonConverter(typeof(DevicePropertiesConverter))]
public JToken Properties { get; set; }
}
/// <summary>
///
/// </summary>
public class DevicePropertiesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(JToken);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JToken.ReadFrom(reader);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException("SOD OFF HOSER");
}
}
}

View File

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

View File

@@ -1,162 +1,162 @@
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;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Responsible for updating config at runtime, and writing the updates out to a local file
/// </summary>
public class ConfigWriter
{
public const string LocalConfigFolder = "LocalConfig";
public const long WriteTimeout = 30000;
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;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
/// Responsible for updating config at runtime, and writing the updates out to a local file
/// </summary>
public class ConfigWriter
{
public const string LocalConfigFolder = "LocalConfig";
public const long WriteTimeout = 30000;
public static CTimer WriteTimer;
static CCriticalSection fileLock = new CCriticalSection();
/// <summary>
/// Updates the config properties of a device
/// </summary>
/// <param name="deviceKey"></param>
/// <param name="properties"></param>
/// <returns></returns>
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
{
bool success = false;
// Get the current device config
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
if (deviceConfig != null)
{
// Replace the current properties JToken with the new one passed into this method
deviceConfig.Properties = properties;
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateDeviceConfig(DeviceConfig config)
{
bool success = false;
var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key));
if (deviceConfigIndex >= 0)
{
ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateRoomConfig(DeviceConfig config)
{
bool success = false;
var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key));
if (roomConfigIndex >= 0)
{
ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config;
Debug.Console(1, "Updated room of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
/// <summary>
/// Resets (or starts) the write timer
/// </summary>
static void ResetTimer()
{
if (WriteTimer == null)
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
WriteTimer.Reset(WriteTimeout);
Debug.Console(1, "Config File write timer has been reset.");
}
/// <summary>
/// Writes the current config to a file in the LocalConfig subfolder
/// </summary>
/// <returns></returns>
private static void WriteConfigFile(object o)
{
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
WriteFile(filePath, configData);
}
/// <summary>
/// Writes
/// </summary>
/// <param name="filepath"></param>
/// <param name="o"></param>
public static void WriteFile(string filePath, string configData)
{
if (WriteTimer != null)
WriteTimer.Stop();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(configData);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
}
static CCriticalSection fileLock = new CCriticalSection();
/// <summary>
/// Updates the config properties of a device
/// </summary>
/// <param name="deviceKey"></param>
/// <param name="properties"></param>
/// <returns></returns>
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
{
bool success = false;
// Get the current device config
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
if (deviceConfig != null)
{
// Replace the current properties JToken with the new one passed into this method
deviceConfig.Properties = properties;
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateDeviceConfig(DeviceConfig config)
{
bool success = false;
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
if (deviceConfig != null)
{
deviceConfig = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
public static bool UpdateRoomConfig(DeviceConfig config)
{
bool success = false;
var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
if (deviceConfig != null)
{
deviceConfig = config;
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
success = true;
}
ResetTimer();
return success;
}
/// <summary>
/// Resets (or starts) the write timer
/// </summary>
static void ResetTimer()
{
if (WriteTimer == null)
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
WriteTimer.Reset(WriteTimeout);
Debug.Console(1, "Config File write timer has been reset.");
}
/// <summary>
/// Writes the current config to a file in the LocalConfig subfolder
/// </summary>
/// <returns></returns>
private static void WriteConfigFile(object o)
{
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
WriteFile(filePath, configData);
}
/// <summary>
/// Writes
/// </summary>
/// <param name="filepath"></param>
/// <param name="o"></param>
public static void WriteFile(string filePath, string configData)
{
if (WriteTimer != null)
WriteTimer.Stop();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(configData);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
}
}

View File

@@ -51,13 +51,6 @@ namespace PepperDash.Essentials.Core.Config
[JsonProperty("rooms")]
public List<DeviceConfig> Rooms { get; set; }
public EssentialsConfig()
: base()
{
Rooms = new List<DeviceConfig>();
}
}
/// <summary>

View File

@@ -1,106 +0,0 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro;
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.CrestronIO
{
public class C2NIoController:CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IRelayPorts
{
private C2nIo _device;
public C2NIoController(string key, Func<DeviceConfig, C2nIo> preActivationFunc, DeviceConfig config):base(key, config.Name)
{
AddPreActivationAction(() =>
{
_device = preActivationFunc(config);
RegisterCrestronGenericBase(_device);
});
}
#region Implementation of IComPorts
public CrestronCollection<ComPort> ComPorts
{
get { return _device.ComPorts; }
}
public int NumberOfComPorts
{
get { return _device.NumberOfComPorts; }
}
#endregion
#region Implementation of IIROutputPorts
public CrestronCollection<IROutputPort> IROutputPorts
{
get { return _device.IROutputPorts; }
}
public int NumberOfIROutputPorts
{
get { return _device.NumberOfIROutputPorts; }
}
#endregion
#region Implementation of IRelayPorts
public CrestronCollection<Relay> RelayPorts
{
get { return _device.RelayPorts; }
}
public int NumberOfRelayPorts
{
get { return _device.NumberOfRelayPorts; }
}
#endregion
}
public class C2NIoControllerFactory : EssentialsDeviceFactory<C2NIoController>
{
public C2NIoControllerFactory()
{
TypeNames = new List<string>() { "c2nio" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new C2N-IO Device");
return new C2NIoController(dc.Key, GetC2NIoDevice, dc);
}
static C2nIo GetC2NIoDevice(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 C2nIo", parentKey);
return new C2nIo(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 C2nIo", parentKey);
return new C2nIo(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
}
}

View File

@@ -34,7 +34,7 @@ namespace PepperDash.Essentials.Core
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new DIN-CEN-CN2 Device");
Debug.Console(1, "Factory Attempting to create new C2N-RTHS Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt;

View File

@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro;
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.CrestronIO
{
public class DinIo8Controller:CrestronGenericBaseDevice, IIOPorts
{
private DinIo8 _device;
public DinIo8Controller(string key, Func<DeviceConfig, DinIo8> preActivationFunc, DeviceConfig config):base(key, config.Name)
{
AddPreActivationAction(() =>
{
_device = preActivationFunc(config);
RegisterCrestronGenericBase(_device);
});
}
#region Implementation of IIOPorts
public CrestronCollection<Versiport> VersiPorts
{
get { return _device.VersiPorts; }
}
public int NumberOfVersiPorts
{
get { return _device.NumberOfVersiPorts; }
}
#endregion
}
public class DinIo8ControllerFactory : EssentialsDeviceFactory<DinIo8Controller>
{
public DinIo8ControllerFactory()
{
TypeNames = new List<string>() { "DinIo8" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new DinIo8 Device");
return new DinIo8Controller(dc.Key, GetDinIo8Device, dc);
}
static DinIo8 GetDinIo8Device(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 DinIo8", parentKey);
return new DinIo8(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 DinIo8", parentKey);
return new DinIo8(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
}
}

View File

@@ -15,7 +15,5 @@ namespace PepperDash.Essentials.Core.CrestronIO
public uint PortNumber { get; set; }
[JsonProperty("disablePullUpResistor")]
public bool DisablePullUpResistor { get; set; }
[JsonProperty("minimumChange")]
public int MinimumChange { get; set; }
}
}

View File

@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core
/// Wrapper class for CEN-IO-DIGIN-104 digital input module
/// </summary>
[Description("Wrapper class for the CEN-IO-DIGIN-104 diginal input module")]
public class CenIoDigIn104Controller : CrestronGenericBaseDevice, IDigitalInputPorts
public class CenIoDigIn104Controller : EssentialsDevice, IDigitalInputPorts
{
public CenIoDi104 Di104 { get; private set; }
@@ -52,17 +52,10 @@ namespace PepperDash.Essentials.Core
{
Debug.Console(1, "Factory Attempting to create new CEN-DIGIN-104 Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
if (control == null)
{
Debug.Console(1, "Factory failed to create a new CEN-DIGIN-104 Device, control properties not found");
return null;
}
var ipid = control.IpIdInt;
if (ipid != 0) return new CenIoDigIn104Controller(dc.Key, dc.Name, new CenIoDi104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device using IP-ID-{0}", ipid);
return null;
var control = CommFactory.GetControlPropertiesConfig(dc);
var ipid = control.IpIdInt;
return new CenIoDigIn104Controller(dc.Key, dc.Name, new Crestron.SimplSharpPro.GeneralIO.CenIoDi104(ipid, Global.ControlSystem));
}
}

View File

@@ -1,208 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.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 GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput
{
public Versiport InputPort { get; private set; }
public IntFeedback InputValueFeedback { get; private set; }
public IntFeedback InputMinimumChangeFeedback { get; private set; }
Func<int> InputValueFeedbackFunc
{
get
{
return () => InputPort.AnalogIn;
}
}
Func<int> InputMinimumChangeFeedbackFunc
{
get { return () => InputPort.AnalogMinChange; }
}
public GenericVersiportAnalogInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
InputValueFeedback = new IntFeedback(InputValueFeedbackFunc);
InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc);
AddPostActivationAction(() =>
{
InputPort = postActivationFunc(config);
InputPort.Register();
InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
if (config.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += InputPort_VersiportChange;
Debug.Console(1, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
});
}
/// <summary>
/// Set minimum voltage change for device to update voltage changed method
/// </summary>
/// <param name="value">valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details</param>
public void SetMinimumChange(ushort value)
{
InputPort.AnalogMinChange = value;
}
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{
Debug.Console(1, this, "Versiport change: {0}", args.Event);
if(args.Event == eVersiportEvent.AnalogInChange)
InputValueFeedback.FireUpdate();
if (args.Event == eVersiportEvent.AnalogMinChangeChange)
InputMinimumChangeFeedback.FireUpdate();
}
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new IAnalogInputJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<IAnalogInputJoinMap>(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
InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
InputMinimumChangeFeedback.LinkInputSig(trilist.UShortInput[joinMap.MinimumChange.JoinNumber]);
trilist.SetUShortSigAction(joinMap.MinimumChange.JoinNumber, SetMinimumChange);
}
catch (Exception e)
{
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
Debug.Console(1, this, "Error: {0}", e);
}
trilist.OnlineStatusChange += (d, args) =>
{
if (!args.DeviceOnLine) return;
InputValueFeedback.FireUpdate();
InputMinimumChangeFeedback.FireUpdate();
};
}
void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
throw new NotImplementedException();
}
#endregion
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.Console(0, "GetVersiportAnalogInput: 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, "GetVersiportAnalogInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.Console(0, "GetVersiportAnalogInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.Console(0, "GetVersiportAnalogInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
}
if(!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
{
Debug.Console(0, "GetVersiportAnalogInput: Device {0} does not support AnalogInput on port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
}
return ioPortDevice.VersiPorts[dc.PortNumber];
}
}
public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportAnalogInputDevice>
{
public GenericVersiportAbalogInputDeviceFactory()
{
TypeNames = new List<string>() { "versiportanaloginput" };
}
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 GenericVersiportAnalogInputDevice(dc.Key, dc.Name, GenericVersiportAnalogInputDevice.GetVersiportDigitalInput, props);
return portDevice;
}
}
}

View File

@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.CrestronIO
{
public interface IAnalogInput
{
IntFeedback InputValueFeedback { get; }
}
}

View File

@@ -1,93 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Essentials.Core.Config;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Wrapper class for CEN-IO-IR-104 module
/// </summary>
[Description("Wrapper class for the CEN-IO-IR-104 module")]
public class CenIoIr104Controller : CrestronGenericBaseDevice, IIROutputPorts
{
private readonly CenIoIr104 _ir104;
/// <summary>
/// Constructor
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ir104"></param>
public CenIoIr104Controller(string key, string name, CenIoIr104 ir104)
: base(key, name, ir104)
{
_ir104 = ir104;
}
#region IDigitalInputPorts Members
/// <summary>
/// IR port collection
/// </summary>
public CrestronCollection<IROutputPort> IROutputPorts
{
get { return _ir104.IROutputPorts; }
}
/// <summary>
/// Number of relay ports property
/// </summary>
public int NumberOfIROutputPorts
{
get { return _ir104.NumberOfIROutputPorts; }
}
#endregion
}
/// <summary>
/// CEN-IO-IR-104 controller fatory
/// </summary>
public class CenIoIr104ControllerFactory : EssentialsDeviceFactory<CenIoIr104Controller>
{
/// <summary>
/// Constructor
/// </summary>
public CenIoIr104ControllerFactory()
{
TypeNames = new List<string>() { "cenioir104" };
}
/// <summary>
/// Build device CEN-IO-IR-104
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new CEN-IO-IR-104 Device");
var control = CommFactory.GetControlPropertiesConfig(dc);
if (control == null)
{
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device, control properties not found");
return null;
}
var ipid = control.IpIdInt;
if(ipid != 0) return new CenIoIr104Controller(dc.Key, dc.Name, new CenIoIr104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-IR-104 Device using IP-ID-{0}", ipid);
return null;
}
}
}

View File

@@ -1,189 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.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 GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput
{
public Versiport OutputPort { get; private set; }
public BoolFeedback OutputStateFeedback { get; private set; }
Func<bool> OutputStateFeedbackFunc
{
get
{
return () => OutputPort.DigitalOut;
}
}
public GenericVersiportDigitalOutputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
{
OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc);
AddPostActivationAction(() =>
{
OutputPort = postActivationFunc(config);
OutputPort.Register();
if (!OutputPort.SupportsDigitalOutput)
{
Debug.Console(0, this, "Device does not support configuration as a Digital Output");
return;
}
OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
OutputPort.VersiportChange += OutputPort_VersiportChange;
});
}
void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args)
{
Debug.Console(1, this, "Versiport change: {0}", args.Event);
if(args.Event == eVersiportEvent.DigitalOutChange)
OutputStateFeedback.FireUpdate();
}
/// <summary>
/// Set value of the versiport digital output
/// </summary>
/// <param name="state">value to set the output to</param>
public void SetOutput(bool state)
{
if (OutputPort.SupportsDigitalOutput)
{
Debug.Console(0, this, "Passed the Check");
OutputPort.DigitalOut = state;
}
else
{
Debug.Console(0, this, "Versiport does not support Digital Output Mode");
}
}
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new IDigitalOutputJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<IDigitalOutputJoinMap>(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
OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
trilist.SetBoolSigAction(joinMap.OutputState.JoinNumber, SetOutput);
}
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 GetVersiportDigitalOutput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.Console(0, "GetVersiportDigitalOuptut: 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, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.Console(0, "GetVersiportDigitalOuptut: Device '0' is not a valid IOPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.Console(0, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
var port = ioPortDevice.VersiPorts[dc.PortNumber];
return port;
}
}
public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{
public GenericVersiportDigitalOutputDeviceFactory()
{
TypeNames = new List<string>() { "versiportoutput" };
}
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 GenericVersiportDigitalOutputDevice(dc.Key, dc.Name, GenericVersiportDigitalOutputDevice.GetVersiportDigitalOutput, props);
return portDevice;
}
}
}

View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core.CrestronIO
{
/// <summary>
/// Represents a device that provides digital input
/// </summary>
public interface IDigitalOutput
{
BoolFeedback OutputStateFeedback { get; }
void SetOutput(bool state);
}
}

View File

@@ -1,77 +0,0 @@
using System.Collections.Generic;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Wrapper class for CEN-IO-RY-104 relay module
/// </summary>
[Description("Wrapper class for the CEN-IO-RY-104 relay module")]
public class CenIoRy104Controller : CrestronGenericBaseDevice, IRelayPorts
{
private readonly CenIoRy104 _ry104;
/// <summary>
/// Constructor
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="ry104"></param>
public CenIoRy104Controller(string key, string name, CenIoRy104 ry104)
: base(key, name, ry104)
{
_ry104 = ry104;
}
/// <summary>
/// Relay port collection
/// </summary>
public CrestronCollection<Relay> RelayPorts
{
get { return _ry104.RelayPorts; }
}
/// <summary>
/// Number of relay ports property
/// </summary>
public int NumberOfRelayPorts
{
get { return _ry104.NumberOfRelayPorts; }
}
}
/// <summary>
/// CEN-IO-RY Controller factory
/// </summary>
public class CenIoRy104ControllerFactory : EssentialsDeviceFactory<CenIoRy104Controller>
{
/// <summary>
/// Constructor
/// </summary>
public CenIoRy104ControllerFactory()
{
TypeNames = new List<string>() { "ceniory104" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create a new CEN-IO-RY-104 Device");
var controlPropertiesConfig = CommFactory.GetControlPropertiesConfig(dc);
if (controlPropertiesConfig == null)
{
Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device, control properties not found");
return null;
}
var ipid = controlPropertiesConfig.IpIdInt;
if (ipid != 0) return new CenIoRy104Controller(dc.Key, dc.Name, new CenIoRy104(ipid, Global.ControlSystem));
Debug.Console(1, "Factory failed to create a new CEN-IO-RY-104 Device using IP-ID-{0}", ipid);
return null;
}
}
}

View File

@@ -44,12 +44,6 @@ namespace PepperDash.Essentials.Core.CrestronIO
{
RelayOutput = postActivationFunc(config);
if (RelayOutput == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Unable to get parent relay device for device key {0} and port {1}", config.PortDeviceKey, config.PortNumber);
return;
}
RelayOutput.Register();
RelayOutput.StateChange += RelayOutput_StateChange;
@@ -67,36 +61,33 @@ namespace PepperDash.Essentials.Core.CrestronIO
{
if (!Global.ControlSystem.SupportsRelay)
{
Debug.Console(0, "Processor does not support relays");
Debug.Console(0, "GetRelayDevice: Processor does not support relays");
return null;
}
relayDevice = Global.ControlSystem;
return relayDevice.RelayPorts[dc.PortNumber];
}
var essentialsDevice = DeviceManager.GetDeviceForKey(dc.PortDeviceKey);
if (essentialsDevice == null)
else
{
Debug.Console(0, "Device {0} was not found in Device Manager. Check configuration or for errors with device.", dc.PortDeviceKey);
return null;
var relayDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IRelayPorts;
if (relayDev == null)
{
Debug.Console(0, "GetRelayDevice: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
relayDevice = relayDev;
}
relayDevice = essentialsDevice as IRelayPorts;
if (relayDevice == null)
{
Debug.Console(0, "Device {0} is not a valid relay parent. Please check configuration.", dc.PortDeviceKey);
Debug.Console(0, "GetRelayDevice: Device '0' is not a valid IRelayPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber <= relayDevice.NumberOfRelayPorts)
if (dc.PortNumber > relayDevice.NumberOfRelayPorts)
{
return relayDevice.RelayPorts[dc.PortNumber];
Debug.Console(0, "GetRelayDevice: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
Debug.Console(0, "Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
return null;
return relayDevice.RelayPorts[dc.PortNumber];
}
#endregion
@@ -209,6 +200,58 @@ namespace PepperDash.Essentials.Core.CrestronIO
var portDevice = new GenericRelayDevice(dc.Key, dc.Name, GetRelay, props);
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
}
*/
}
}

View File

@@ -69,34 +69,19 @@ namespace PepperDash.Essentials.Core
public override bool CustomActivate()
{
Debug.Console(0, this, "Activating");
if (!PreventRegistration)
{
if (!PreventRegistration)
{
//Debug.Console(1, this, " Does not require registration. Skipping");
if (Hardware.Registerable && !Hardware.Registered)
{
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
}
var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false;
}
IsRegistered.FireUpdate();
}
else
{
AddPostActivationAction(() =>
{
if (Hardware.Registerable && !Hardware.Registered)
{
var response = Hardware.RegisterWithLogging(Key);
}
IsRegistered.FireUpdate();
});
}
}
foreach (var f in Feedbacks)
{
@@ -145,12 +130,6 @@ 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)

View File

@@ -0,0 +1,62 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace PepperDash.Essentials.Core.Devices.Codec
{
public class CodecActiveCallItem
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("number")]
public string Number { get; set; }
[JsonProperty("type")]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallType Type { get; set; }
[JsonProperty("status")]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallStatus Status { get; set; }
[JsonProperty("direction")]
[JsonConverter(typeof(StringEnumConverter))]
public eCodecCallDirection Direction { get; set; }
[JsonProperty("id")]
public string Id { get; set; }
//public object CallMetaData { get; set; }
/// <summary>
/// Returns true when this call is any status other than
/// Unknown, Disconnected, Disconnecting
/// </summary>
[JsonProperty("isActiveCall")]
public bool IsActiveCall
{
get
{
return !(Status == eCodecCallStatus.Disconnected
|| Status == eCodecCallStatus.Disconnecting
|| Status == eCodecCallStatus.Idle
|| Status == eCodecCallStatus.Unknown);
}
}
}
/// <summary>
///
/// </summary>
public class CodecCallStatusItemChangeEventArgs : EventArgs
{
public CodecActiveCallItem CallItem { get; private set; }
public CodecCallStatusItemChangeEventArgs(CodecActiveCallItem item)
{
CallItem = item;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
namespace PepperDash.Essentials.Devices.Common.Codec
{
public interface IHasExternalSourceSwitching
{
bool ExternalSourceListEnabled { get; }
string ExternalSourceInputPort { get; }
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
void SetExternalSourceState(string key, eExternalSourceMode mode);
void ClearExternalSources();
void SetSelectedSource(string key);
Action<string, string> RunRouteAction { set;}
}
public enum eExternalSourceType { camera, desktop, document_camera, mediaplayer, PC, whiteboard, other }
public enum eExternalSourceMode { Ready, NotReady, Hidden, Error }
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
public interface IHasParticipants
{
CodecParticipants Participants { get; }
}
public interface IHasParticipantVideoMute:IHasParticipants
{
void MuteVideoForParticipant(int userId);
void UnmuteVideoForParticipant(int userId);
void ToggleVideoForParticipant(int userId);
}
public interface IHasParticipantAudioMute:IHasParticipantVideoMute
{
void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId);
}
public class CodecParticipants
{
private List<Participant> _currentParticipants;
public List<Participant> CurrentParticipants {
get { return _currentParticipants; }
set
{
_currentParticipants = value;
var handler = ParticipantsListHasChanged;
if(handler == null) return;
handler(this, new EventArgs());
}
}
public event EventHandler<EventArgs> ParticipantsListHasChanged;
public CodecParticipants()
{
_currentParticipants = new List<Participant>();
}
}
public class Participant
{
public bool IsHost { get; set; }
public string Name { get; set; }
public bool CanMuteVideo { get; set; }
public bool CanUnmuteVideo { get; set; }
public bool VideoMuteFb { get; set; }
public bool AudioMuteFb { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Devices;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface IHasSelfviewPosition
{
StringFeedback SelfviewPipPositionFeedback { get; }
void SelfviewPipPositionSet(CodecCommandWithLabel position);
void SelfviewPipPositionToggle();
}
}

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