Compare commits

..

6 Commits

Author SHA1 Message Date
Neil Dorin
61a2597b7e Adds IHasCameraOff to CameraVisca 2020-11-09 10:13:53 -07:00
Neil Dorin
e11cde9ec9 Merge branch 'development' into feature/add-camera-config-props 2020-10-16 11:20:52 -06:00
Andrew Welker
1745431188 Merge branch 'development' into feature/add-camera-config-props 2020-09-10 16:00:11 -06:00
Neil Dorin
709fb38e45 Remove zoom speeds 2020-09-10 15:34:28 -06:00
Neil Dorin
7ebd9e874f Adds SpeedTimer implmentation to CameraVisca 2020-09-10 15:24:08 -06:00
Neil Dorin
8e20cf62c3 Adds feedback parsing to CameraVisca as well as some new focus controls. 2020-09-09 17:44:48 -06:00
147 changed files with 14395 additions and 20538 deletions

View File

@@ -32,6 +32,7 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: true
# Fetch all tags
- name: Fetch tags
run: git fetch --tags
@@ -40,11 +41,12 @@ jobs:
shell: powershell
run: |
$version = ./.github/scripts/GenerateVersionNumber.ps1
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Write-Output "::set-env name=VERSION::$version"
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
@@ -58,7 +60,7 @@ jobs:
- name: Build Solution
shell: powershell
run: |
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder:v1.4.1 c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
# Zip up the output files as needed
- name: Zip Build Output
shell: powershell
@@ -78,9 +80,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 }}
@@ -114,7 +123,7 @@ jobs:
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
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
- name: Download Build output
@@ -143,3 +152,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"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Create new branch
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- name: Copy Files to root & delete output directory
run: |
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
Remove-Item -Path .\output -Recurse
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: |
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
Write-Host "Branch: $branch"
git push -u origin $($branch) --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./
# This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
Public_Push_Output:
needs: Build_Project
runs-on: windows-latest
if: contains(github.ref, 'main') || contains(github.ref, '/release/')
steps:
# Checkout the repo
- name: check Github ref
run: ${{toJson(github.ref)}}
- name: Checkout Builds Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.BUILDS_TOKEN }}
repository: PepperDash/Essentials-Builds
ref: ${{ Env.GITHUB_REF }}
# Download the version artifact from the build job
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Check Directory
run: Get-ChildItem "./"
# Set the version number environment variable from the file we just downloaded
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Create new branch
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- name: Copy Files to root & delete output directory
run: |
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
Remove-Item -Path .\output -Recurse
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: |
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
Write-Host "Branch: $branch"
git push -u origin $($branch) --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./

View File

@@ -24,18 +24,25 @@ jobs:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
# And any submodules
- name: Checkout submodules
shell: bash
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
env:
TAG_NAME: ${{ github.event.release.tag_name }}
run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
run: Write-Output "::set-env name=VERSION::$($Env:TAG_NAME)"
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
@@ -94,7 +101,7 @@ jobs:
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
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
- name: Download Build output
@@ -123,3 +130,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"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout/Create the branch
- name: Checkout main branch
run: git checkout main
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- name: Copy Files to root & delete output directory
run: |
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
Remove-Item -Path .\output -Recurse
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: git push -u origin main --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./
# This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
Public_Push_Output:
needs: Build_Project
runs-on: windows-latest
steps:
# Checkout the repo
- name: Checkout Builds Repo
uses: actions/checkout@v2
with:
token: ${{ secrets.BUILDS_TOKEN }}
repository: PepperDash/Essentials-Builds
ref: ${{ Env.GITHUB_REF }}
# Download the version artifact from the build job
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Check Directory
run: Get-ChildItem "./"
# Set the version number environment variable from the file we just downloaded
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version"
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
# Checkout main branch
- name: Create new branch
run: git checkout main
# Download the build output into the repo
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Check directory
run: Get-ChildItem ./
# Unzip the build package file
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Check directory again
run: Get-ChildItem ./
# Copy Contents of output folder to root directory
- name: Copy Files to root & delete output directory
run: |
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
Remove-Item -Path .\output -Recurse
# Commits the build output to the branch and tags it with the version
- name: Commit build output and tag the commit
shell: powershell
run: |
git config user.email "actions@pepperdash.com"
git config user.name "GitHub Actions"
git add .
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
Write-Host "Commit: $commit"
git commit -m $commit
git tag $($Env:VERSION)
# Push the commit
- name: Push to Builds Repo
shell: powershell
run: git push -u origin main --force
# Push the tags
- name: Push tags
run: git push --tags origin
- name: Check Directory
run: Get-ChildItem ./

1
.gitignore vendored
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

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

@@ -12,11 +12,11 @@ using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Fusion;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Config;
//using PepperDash.Essentials.Room.MobileControl;
using Newtonsoft.Json;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
@@ -53,7 +53,7 @@ namespace PepperDash.Essentials
if (Debug.DoNotLoadOnNextBoot)
{
CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file",
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
ConsoleAccessLevelEnum.AccessOperator);
}
@@ -130,7 +130,7 @@ namespace PepperDash.Essentials
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString());
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"
@@ -290,14 +290,33 @@ namespace PepperDash.Essentials
DeviceManager.ActivateAll();
var mobileControl = GetMobileControlDevice();
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl;
if (mobileControl == null) return;
mobileControl.LinkSystemMonitorToAppServer();
//LinkSystemMonitorToAppServer();
}
//void LinkSystemMonitorToAppServer()
//{
// var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
// var appServer = DeviceManager.GetDeviceForKey("appServer") as MobileControlSystemController;
// if (sysMon != null && appServer != null)
// {
// var key = sysMon.Key + "-" + appServer.Key;
// var messenger = new PepperDash.Essentials.AppServer.Messengers.SystemMonitorMessenger
// (key, sysMon, "/device/systemMonitor");
// messenger.RegisterWithAppServer(appServer);
// DeviceManager.AddDevice(messenger);
// }
//}
/// <summary>
/// Reads all devices from config and adds them to DeviceManager
/// </summary>
@@ -323,12 +342,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());
@@ -380,14 +394,19 @@ namespace PepperDash.Essentials
if (newDev == null)
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
//
//if (newDev == null)
// newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
//
if (newDev != null)
DeviceManager.AddDevice(newDev);
else
Debug.Console(0, Debug.ErrorLogLevel.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.");
@@ -437,34 +456,19 @@ namespace PepperDash.Essentials
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
if (room != null)
{
// default IPID
uint fusionIpId = 0xf1;
// default to no join map key
string fusionJoinMapKey = string.Empty;
if (room.Config.Properties["fusion"] != null)
{
Debug.Console(2, "Custom Fusion config found. Using custom values");
var fusionConfig = room.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
if (fusionConfig != null)
{
fusionIpId = fusionConfig.IpIdInt;
fusionJoinMapKey = fusionConfig.JoinMapKey;
}
}
if (room is EssentialsHuddleSpaceRoom)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
// Mobile Control bridge
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
//DeviceManager.AddDevice(bridge);
CreateMobileControlBridge(room);
}
@@ -473,21 +477,13 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
}
else if (room is EssentialsTechRoom)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice,
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
// Mobile Control bridge
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
//DeviceManager.AddDevice(bridge);
CreateMobileControlBridge(room);
}
@@ -508,55 +504,40 @@ namespace PepperDash.Essentials
private static void CreateMobileControlBridge(EssentialsRoomBase room)
{
var mobileControl = GetMobileControlDevice();
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl;
if (mobileControl == null) return;
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
mobileControl.CreateMobileControlRoomBridge(room);
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>
/// Helps add the post activation steps that link bridges to main controller
/// </summary>
/// <param name="bridge"></param>
//void AddBridgePostActivationHelper(MobileControlBridgeBase bridge)
//{
// bridge.AddPostActivationAction(() =>
// {
// var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
// if (parent == null)
// {
// Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present");
// return;
// }
// Debug.Console(0, bridge, "Linking to parent controller");
// bridge.AddParent(parent);
// parent.AddBridge(bridge);
// });
//}
/// <summary>
/// Fires up a logo server if not already running
/// </summary>
void LoadLogoServer()
{
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");
@@ -566,38 +547,5 @@ namespace PepperDash.Essentials
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;
try
{
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"));
}
catch
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config");
return false;
}
}
}
}

View File

@@ -16,8 +16,8 @@ namespace PepperDash.Essentials.Fusion
{
BooleanSigData CodecIsInCall;
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
: base(room, ipId, joinMapKey)
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
: base(room, ipId)
{
}
@@ -55,25 +55,25 @@ namespace PepperDash.Essentials.Fusion
// Map FusionRoom Attributes:
// Codec volume
var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig);
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(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly);
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", 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);
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, JoinMap.VcCodecOnline.AttributeName);
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
}
// Codec IP Address
@@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion
if (codecHasIpInfo)
{
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly);
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly);
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
@@ -123,7 +123,7 @@ namespace PepperDash.Essentials.Fusion
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
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);
@@ -166,19 +166,20 @@ namespace PepperDash.Essentials.Fusion
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "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);
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.
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
@@ -196,9 +197,9 @@ namespace PepperDash.Essentials.Fusion
uint i = 1;
foreach (var kvp in setTopBoxes)
{
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
if (i > 5) // We only have five spots
break;
}
@@ -206,7 +207,7 @@ namespace PepperDash.Essentials.Fusion
i = 1;
foreach (var kvp in discPlayers)
{
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > 5) // We only have five spots
break;
@@ -216,9 +217,9 @@ namespace PepperDash.Essentials.Fusion
i = 1;
foreach (var kvp in laptops)
{
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
if (i > 10) // We only have ten spots???
break;
}
@@ -272,17 +273,14 @@ namespace PepperDash.Essentials.Fusion
// 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);
}
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
MapDisplayToRoomJoins(1, 158, defaultDisplay);
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
@@ -304,18 +302,8 @@ namespace PepperDash.Essentials.Fusion
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
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);
}
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
@@ -327,7 +315,7 @@ namespace PepperDash.Essentials.Fusion
}
protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
{
string displayName = string.Format("Display {0} - ", displayIndex);
@@ -337,17 +325,12 @@ namespace PepperDash.Essentials.Fusion
// Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Power Off
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
var displayTwoWay = display as IHasPowerControlWithFeedback;
if (displayTwoWay != null)
{
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
}
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);

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

@@ -133,7 +133,6 @@
<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" />
@@ -142,13 +141,11 @@
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
<Compile Include="Room\Config\EssentialsTechRoomConfig.cs" />
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />

View File

@@ -22,25 +22,30 @@ namespace PepperDash.Essentials.Room.Config
public static Device GetRoomObject(DeviceConfig roomConfig)
{
var typeName = roomConfig.Type.ToLower();
if (typeName == "huddle")
{
return new EssentialsHuddleSpaceRoom(roomConfig);
}
if (typeName == "huddlevtc1")
{
return new EssentialsHuddleVtc1Room(roomConfig);
}
if (typeName == "ddvc01bridge")
{
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
}
if (typeName == "dualdisplay")
{
return new EssentialsDualDisplayRoom(roomConfig);
}
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
return typeName != "techroom" ? null : new EssentialsTechRoom(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>
@@ -177,9 +182,6 @@ namespace PepperDash.Essentials.Room.Config
[JsonProperty("volumes")]
public EssentialsRoomVolumesConfig Volumes { get; set; }
[JsonProperty("fusion")]
public EssentialsRoomFusionConfig Fusion { get; set; }
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
@@ -223,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,72 +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; }
/// <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

@@ -274,45 +274,28 @@ namespace PepperDash.Essentials
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)
{
// Link power, warming, cooling to display
var dispTwoWay = disp as IHasPowerControlWithFeedback;
if (dispTwoWay != null)
{
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
disp.CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
};
}
if (!disp.PowerIsOnFeedback.BoolValue)
disp.CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (disp.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
};
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
@@ -346,6 +329,7 @@ namespace PepperDash.Essentials
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
this.SourceListKey = PropertiesConfig.SourceListKey;
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
@@ -595,8 +579,8 @@ namespace PepperDash.Essentials
if (dest is IHasPowerControl)
(dest as IHasPowerControl).PowerOff();
if (dest is IPower)
(dest as IPower).PowerOff();
}
else
{

View File

@@ -176,19 +176,15 @@ namespace PepperDash.Essentials
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();
}
};
}
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (!disp.PowerIsOnFeedback.BoolValue)
CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
};
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
@@ -201,25 +197,11 @@ namespace PepperDash.Essentials
IsCoolingDownFeedback.FireUpdate();
};
}
SetSourceListKey();
SourceListKey = "default";
EnablePowerOnToLastSource = true;
}
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
{
SetSourceListKey(PropertiesConfig.SourceListKey);
}
else
{
SetSourceListKey(Key);
}
}
protected override void CustomSetConfig(DeviceConfig config)
{
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
@@ -270,6 +252,7 @@ namespace PepperDash.Essentials
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
this.SourceListKey = PropertiesConfig.SourceListKey;
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
@@ -512,8 +495,8 @@ namespace PepperDash.Essentials
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{
dest.ReleaseRoute();
if (dest is IHasPowerControl)
(dest as IHasPowerControl).PowerOff();
if (dest is IPower)
(dest as IPower).PowerOff();
}
else
{

View File

@@ -13,7 +13,7 @@ using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Devices.Common.Codec;
using PepperDash.Essentials.Devices.Common.VideoCodec;
using PepperDash.Essentials.Devices.Common.AudioCodec;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
using PepperDash_Essentials_Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials
{
@@ -51,6 +51,20 @@ namespace PepperDash.Essentials
//************************
public override string SourceListKey
{
get
{
return _SourceListKey;
}
set
{
_SourceListKey = value;
SetCodecExternalSources();
}
}
protected override Func<bool> OnFeedbackFunc
{
get
@@ -176,12 +190,6 @@ namespace PepperDash.Essentials
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
var vc = VideoCodec as IHasExternalSourceSwitching;
if (vc != null)
{
vc.SetSelectedSource(CurrentSourceInfoKey);
}
}
}
SourceListItem _CurrentSourceInfo;
@@ -265,23 +273,19 @@ namespace PepperDash.Essentials
if (disp != null)
{
// Link power, warming, cooling to display
var dispTwoWay = disp as IHasPowerControlWithFeedback;
if (dispTwoWay != null)
{
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
{
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
};
}
if (!disp.PowerIsOnFeedback.BoolValue)
CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
if (disp.PowerIsOnFeedback.BoolValue)
{
SetDefaultLevels();
}
};
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{
@@ -324,8 +328,7 @@ namespace PepperDash.Essentials
CallTypeFeedback = new IntFeedback(() => 0);
SetSourceListKey();
SourceListKey = "default";
EnablePowerOnToLastSource = true;
}
catch (Exception e)
@@ -334,21 +337,6 @@ namespace PepperDash.Essentials
}
}
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
{
SetSourceListKey(PropertiesConfig.SourceListKey);
}
else
{
SetSourceListKey(Key);
}
SetCodecExternalSources();
}
protected override void CustomSetConfig(DeviceConfig config)
{
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
@@ -372,14 +360,13 @@ namespace PepperDash.Essentials
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
this.SourceListKey = PropertiesConfig.SourceListKey;
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
return base.CustomActivate();
}
/// <summary>
///
/// </summary>
@@ -396,8 +383,6 @@ namespace PepperDash.Essentials
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
RunRouteAction("roomOff");
VideoCodec.StopSharing();
VideoCodec.StandbyActivate();
}
/// <summary>
@@ -595,28 +580,6 @@ namespace PepperDash.Essentials
OnFeedback.FireUpdate();
if (OnFeedback.BoolValue)
{
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
{
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
VideoCodec.StandbyDeactivate();
}
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
{
VideoCodec.StandbyDeactivate();
}
else
{
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
}
}
else
{
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
}
// report back when done
if (successCallback != null)
successCallback();
@@ -677,9 +640,8 @@ namespace PepperDash.Essentials
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{
dest.ReleaseRoute();
if (dest is IHasPowerControl)
(dest as IHasPowerControl).PowerOff();
if (dest is IPower)
(dest as IPower).PowerOff();
}
else
{
@@ -731,44 +693,37 @@ namespace PepperDash.Essentials
}
/// <summary>
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
/// </summary>
private void SetCodecExternalSources()
{
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
/// <summary>
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
/// </summary>
private void SetCodecExternalSources()
{
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
{
return;
}
if (videoCodecWithExternalSwitching == null)
{
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;
string codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort;
videoCodecWithExternalSwitching.ClearExternalSources();
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
videoCodecWithExternalSwitching.ClearExternalSources();
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
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;
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
{
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);
}
}
videoCodecWithExternalSwitching.AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
}
}
}
private void SetCodecBranding()
{

View File

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

View File

@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Net.Http;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
@@ -13,12 +16,12 @@ namespace PepperDash.Essentials
/// <summary>
///
/// </summary>
readonly HttpServer _server;
HttpServer Server;
/// <summary>
///
/// </summary>
readonly string _fileDirectory;
string FileDirectory;
/// <summary>
///
@@ -42,17 +45,18 @@ namespace PepperDash.Essentials
//{ ".js", "application/javascript" },
//{ ".json", "application/json" },
//{ ".map", "application/x-navimap" },
{ ".pdf", "application/pdf" },
{ ".pdf", "application.pdf" },
{ ".png", "image/png" },
//{ ".txt", "text/plain" },
};
_server = new HttpServer {Port = port};
_fileDirectory = directory;
_server.OnHttpRequest += Server_OnHttpRequest;
_server.Open();
Server = new HttpServer();
Server.Port = port;
FileDirectory = directory;
Server.OnHttpRequest += new OnHttpRequestHandler(Server_OnHttpRequest);
Server.Open();
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
}
/// <summary>
@@ -63,40 +67,27 @@ namespace PepperDash.Essentials
var path = args.Request.Path;
Debug.Console(2, "HTTP Request with path: '{0}'", args.Request.Path);
try
if (File.Exists(FileDirectory + path))
{
if (File.Exists(_fileDirectory + path))
{
var filePath = path.Replace('/', '\\');
var localPath = string.Format(@"{0}{1}", _fileDirectory, filePath);
string filePath = path.Replace('/', '\\');
string localPath = string.Format(@"{0}{1}", FileDirectory, filePath);
Debug.Console(2, "HTTP Logo Server attempting to find file: '{0}'", localPath);
if (File.Exists(localPath))
{
args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension);
args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
}
else
{
Debug.Console(2, "HTTP Logo Server Cannot find file '{0}'", localPath);
args.Response.ContentString = string.Format("Not found: '{0}'", filePath);
args.Response.Code = 404;
}
Debug.Console(2, "HTTP Logo Server attempting to find file: '{0}'", localPath);
if (File.Exists(localPath))
{
args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension);
args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
}
else
{
Debug.Console(2, "HTTP Logo Server: '{0}' does not exist", _fileDirectory + path);
args.Response.ContentString = string.Format("Not found: '{0}'", _fileDirectory + path);
Debug.Console(2, "HTTP Logo Server Cannot find file '{0}'", localPath);
args.Response.ContentString = string.Format("Not found: '{0}'", filePath);
args.Response.Code = 404;
}
}
catch (Exception ex)
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception getting file: {0}", ex.Message);
Debug.Console(0, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
args.Response.Code = 400;
args.Response.ContentString = string.Format("invalid request");
Debug.Console(2, "HTTP Logo Server: '{0}' does not exist", FileDirectory + path);
}
}
@@ -106,7 +97,7 @@ namespace PepperDash.Essentials
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{
if (programEventType == eProgramStatusEventType.Stopping)
_server.Close();
Server.Close();
}
/// <summary>
@@ -116,7 +107,11 @@ namespace PepperDash.Essentials
/// <returns></returns>
public static string GetContentType(string extension)
{
var type = ExtensionContentTypes.ContainsKey(extension) ? ExtensionContentTypes[extension] : "text/plain";
string type;
if (ExtensionContentTypes.ContainsKey(extension))
type = ExtensionContentTypes[extension];
else
type = "text/plain";
return type;
}
}

View File

@@ -305,9 +305,9 @@ namespace PepperDash.Essentials
TriList.SetSigFalseAction(UIBoolJoin.ShowPowerOffPress, EndMeetingPress);
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
{
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
{
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
});
base.Show();
@@ -984,8 +984,8 @@ namespace PepperDash.Essentials
(previousDev as IDvr).UnlinkButtons(TriList);
if (previousDev is INumericKeypad)
(previousDev as INumericKeypad).UnlinkButtons(TriList);
if (previousDev is IHasPowerControl)
(previousDev as IHasPowerControl).UnlinkButtons(TriList);
if (previousDev is IPower)
(previousDev as IPower).UnlinkButtons(TriList);
if (previousDev is ITransport)
(previousDev as ITransport).UnlinkButtons(TriList);
//if (previousDev is IRadio)
@@ -1044,8 +1044,8 @@ namespace PepperDash.Essentials
(dev as IDvr).LinkButtons(TriList);
if (dev is INumericKeypad)
(dev as INumericKeypad).LinkButtons(TriList);
if (dev is IHasPowerControl)
(dev as IHasPowerControl).LinkButtons(TriList);
if (dev is IPower)
(dev as IPower).LinkButtons(TriList);
if (dev is ITransport)
(dev as ITransport).LinkButtons(TriList);
//if (dev is IRadio)

View File

@@ -319,8 +319,8 @@ namespace PepperDash.Essentials
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
{
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
});
SetupNextMeetingTimer();
@@ -1293,8 +1293,8 @@ namespace PepperDash.Essentials
(previousDev as IDvr).UnlinkButtons(TriList);
if (previousDev is INumericKeypad)
(previousDev as INumericKeypad).UnlinkButtons(TriList);
if (previousDev is IHasPowerControl)
(previousDev as IHasPowerControl).UnlinkButtons(TriList);
if (previousDev is IPower)
(previousDev as IPower).UnlinkButtons(TriList);
if (previousDev is ITransport)
(previousDev as ITransport).UnlinkButtons(TriList);
}
@@ -1351,8 +1351,8 @@ namespace PepperDash.Essentials
(dev as IDvr).LinkButtons(TriList);
if (dev is INumericKeypad)
(dev as INumericKeypad).LinkButtons(TriList);
if (dev is IHasPowerControl)
(dev as IHasPowerControl).LinkButtons(TriList);
if (dev is IPower)
(dev as IPower).LinkButtons(TriList);
if (dev is ITransport)
(dev as ITransport).LinkButtons(TriList);
}

View File

@@ -78,7 +78,7 @@ 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; }
@@ -98,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);
@@ -152,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();
@@ -172,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>
@@ -335,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
@@ -351,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
{
@@ -367,18 +303,6 @@ 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>

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

@@ -76,14 +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("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 });

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

@@ -1,274 +1,131 @@
using System;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
{
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
{
[JoinName("IsOnline")]
public JoinDataComplete IsOnline = new JoinDataComplete(
new JoinData
{
JoinNumber = 1,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Is Online",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(
new JoinData
{
JoinNumber = 1,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Name",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("Enable")]
public JoinDataComplete Enable = new JoinDataComplete(
new JoinData
{
JoinNumber = 2,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Enable",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PartitionSensed")]
public JoinDataComplete PartitionSensed = new JoinDataComplete(
new JoinData
{
JoinNumber = 3,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Partition Sensed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("PartitionNotSensed")]
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
new JoinData
{
JoinNumber = 4,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Partition Not Sensed",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("IncreaseSensitivity")]
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
new JoinData
{
JoinNumber = 6,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Increase Sensitivity",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DecreaseSensitivity")]
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
new JoinData
{
JoinNumber = 7,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Decrease Sensitivity",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("Sensitivity")]
public JoinDataComplete Sensitivity = new JoinDataComplete(
new JoinData
{
JoinNumber = 2,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Sensor Sensitivity",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Analog
});
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
public GlsPartitionSensorJoinMap(uint joinStart)
: this(joinStart, typeof(GlsPartitionSensorJoinMap))
{
}
/// <summary>
/// Constructor to use when extending this Join map
/// </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,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,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

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

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

@@ -96,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

@@ -33,6 +33,7 @@ namespace PepperDash.Essentials.Core
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)
{
@@ -40,6 +41,7 @@ namespace PepperDash.Essentials.Core
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);
}
public void SendTextNoResponse(string format, params object[] items)
@@ -48,6 +50,7 @@ namespace PepperDash.Essentials.Core
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)
@@ -60,6 +63,10 @@ namespace PepperDash.Essentials.Core
{
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());
}
}

View File

@@ -7,8 +7,6 @@ using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using Newtonsoft.Json.Linq;
namespace PepperDash.Essentials.Core.Config
{
/// <summary>
@@ -29,7 +27,7 @@ namespace PepperDash.Essentials.Core.Config
public List<TieLineConfig> TieLines { get; set; }
[JsonProperty("joinMaps")]
public Dictionary<string, JObject> JoinMaps { get; set; }
public Dictionary<string, string> JoinMaps { get; set; }
/// <summary>
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null

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

@@ -73,21 +73,21 @@ namespace PepperDash.Essentials.Core.CrestronIO.Cards
string cardType;
if (!_config.Cards.TryGetValue(i, out cardType))
{
Debug.Console(0, this, "No card found for slot {0}", i);
Debug.Console(1, this, "No card found for slot {0}", i);
continue;
}
if (String.IsNullOrEmpty(cardType))
{
Debug.Console(0, this, "No card specified for slot {0}", i);
continue;
return;
}
Func<uint, C3CardControllerBase> cardBuilder;
if (!_cardDict.TryGetValue(cardType.ToLower(), out cardBuilder))
{
Debug.Console(0, "Unable to find factory for 3-Series card type {0}.", cardType);
continue;
return;
}
try

View File

@@ -1,39 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO
{
[Description("Wrapper class for Digital Input")]
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
{
public DigitalInput InputPort { get; private set; }
public BoolFeedback InputStateFeedback { get; private set; }
Func<bool> InputStateFeedbackFunc
{
get
{
return () => InputPort.State;
}
}
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
{
public DigitalInput InputPort { get; private set; }
public BoolFeedback InputStateFeedback { get; private set; }
Func<bool> InputStateFeedbackFunc
{
get
{
return () => InputPort.State;
}
}
public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
IOPortConfig config)
: base(key, name)
{
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
AddPostActivationAction(() =>
{
@@ -41,15 +40,15 @@ namespace PepperDash.Essentials.Core.CrestronIO
InputPort.Register();
InputPort.StateChange += InputPort_StateChange;
InputPort.StateChange += InputPort_StateChange;
});
}
#region Events
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
{
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
{
InputStateFeedback.FireUpdate();
}
@@ -82,7 +81,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
if (ioPortDevice == null)
{
Debug.Console(0, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey);
Debug.Console(0, "GetDigitalInput: Device '0' is not a valid IRelayPorts Device", dc.PortDeviceKey);
return null;
}
@@ -100,13 +99,13 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new IDigitalInputJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
var joinMap = new IDigitalInputJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
if (bridge != null)
@@ -116,19 +115,19 @@ namespace PepperDash.Essentials.Core.CrestronIO
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
try
{
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
Debug.Console(1, this, "Error: {0}", e);
}
try
{
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
Debug.Console(1, this, "Error: {0}", e);
}
}
@@ -145,7 +144,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new Generic Digital Input Device");
Debug.Console(1, "Factory Attempting to create new Generic Relay Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
@@ -159,7 +158,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
#endregion
}
}
}

View File

@@ -4,21 +4,15 @@ using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core.CrestronIO
{
/// <summary>
/// Represents a generic digital input deviced tied to a versiport
/// </summary>
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
public class GenericVersiportDigitalInputDevice : EssentialsDevice, IDigitalInput
{
public Versiport InputPort { get; private set; }
@@ -32,29 +26,17 @@ namespace PepperDash.Essentials.Core.CrestronIO
}
}
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
base(key, name)
public GenericVersiportDigitalInputDevice(string key, Versiport inputPort, IOPortConfig props):
base(key)
{
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
InputPort = inputPort;
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
if (props.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += new VersiportEventHandler(InputPort_VersiportChange);
AddPostActivationAction(() =>
{
InputPort = postActivationFunc(config);
InputPort.Register();
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
if (config.DisablePullUpResistor)
InputPort.DisablePullUpResistor = true;
InputPort.VersiportChange += InputPort_VersiportChange;
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
});
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", props.PortNumber, InputPort.DisablePullUpResistor);
}
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
@@ -64,105 +46,5 @@ namespace PepperDash.Essentials.Core.CrestronIO
if(args.Event == eVersiportEvent.DigitalInChange)
InputStateFeedback.FireUpdate();
}
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new IDigitalInputJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
try
{
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
// Link feedback for input state
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
}
catch (Exception e)
{
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
Debug.Console(1, this, "Error: {0}", e);
}
}
#endregion
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
{
IIOPorts ioPortDevice;
if (dc.PortDeviceKey.Equals("processor"))
{
if (!Global.ControlSystem.SupportsVersiport)
{
Debug.Console(0, "GetVersiportDigitalInput: Processor does not support Versiports");
return null;
}
ioPortDevice = Global.ControlSystem;
}
else
{
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
if (ioPortDev == null)
{
Debug.Console(0, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
return null;
}
ioPortDevice = ioPortDev;
}
if (ioPortDevice == null)
{
Debug.Console(0, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
return null;
}
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
{
Debug.Console(0, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
}
return ioPortDevice.VersiPorts[dc.PortNumber];
}
}
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
{
public GenericVersiportDigitalInputDeviceFactory()
{
TypeNames = new List<string>() { "versiportinput" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new Generic Versiport Device");
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
if (props == null) return null;
var portDevice = new GenericVersiportDigitalInputDevice(dc.Key, dc.Name, GenericVersiportDigitalInputDevice.GetVersiportDigitalInput, props);
return portDevice;
}
}
}

View File

@@ -1,25 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO
{
/// <summary>
/// Represents a generic device controlled by relays
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.CrestronIO
{
/// <summary>
/// Represents a generic device controlled by relays
/// </summary>
[Description("Wrapper class for a Relay")]
public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput
{
public Relay RelayOutput { get; private set; }
public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput
{
public Relay RelayOutput { get; private set; }
public BoolFeedback OutputIsOnFeedback { get; private set; }
//Maintained for compatibility with PepperDash.Essentials.Core.Devices.CrestronProcessor
@@ -94,11 +94,11 @@ namespace PepperDash.Essentials.Core.CrestronIO
#region Events
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
{
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
{
OutputIsOnFeedback.FireUpdate();
}
}
#endregion
#region Methods
@@ -119,33 +119,33 @@ namespace PepperDash.Essentials.Core.CrestronIO
OpenRelay();
else
CloseRelay();
}
}
#endregion
#region ISwitchedOutput Members
void ISwitchedOutput.On()
{
CloseRelay();
}
void ISwitchedOutput.Off()
{
OpenRelay();
}
#region ISwitchedOutput Members
void ISwitchedOutput.On()
{
CloseRelay();
}
void ISwitchedOutput.Off()
{
OpenRelay();
}
#endregion
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GenericRelayControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
var joinMap = new GenericRelayControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GenericRelayControllerJoinMap>(joinMapSerialized);
if (bridge != null)
@@ -155,26 +155,26 @@ namespace PepperDash.Essentials.Core.CrestronIO
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
if (RelayOutput == null)
{
Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key);
return;
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
trilist.SetBoolSigAction(joinMap.Relay.JoinNumber, b =>
{
if (b)
CloseRelay();
else
OpenRelay();
});
// feedback for relay state
}
if (RelayOutput == null)
{
Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key);
return;
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
trilist.SetBoolSigAction(joinMap.Relay.JoinNumber, b =>
{
if (b)
CloseRelay();
else
OpenRelay();
});
// feedback for relay state
OutputIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Relay.JoinNumber]);
}
@@ -202,54 +202,54 @@ namespace PepperDash.Essentials.Core.CrestronIO
return portDevice;
/*
if (props.PortDeviceKey == "processor")
portDevice = Global.ControlSystem as IRelayPorts;
else
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts;
if (portDevice == null)
Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key);
else
{
var cs = (portDevice as CrestronControlSystem);
if (cs != null)
{
// The relay is on a control system processor
if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts)
{
Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays");
return null;
}
}
else
{
// The relay is on another device type
if (props.PortNumber > portDevice.NumberOfRelayPorts)
{
Debug.Console(0, "Port Device: {0} does not have enough relays");
return null;
}
}
Relay relay = portDevice.RelayPorts[props.PortNumber];
if (!relay.Registered)
{
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
return new GenericRelayDevice(key, relay);
else
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
}
else
{
return new GenericRelayDevice(key, relay);
}
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
}
/*
if (props.PortDeviceKey == "processor")
portDevice = Global.ControlSystem as IRelayPorts;
else
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts;
if (portDevice == null)
Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key);
else
{
var cs = (portDevice as CrestronControlSystem);
if (cs != null)
{
// The relay is on a control system processor
if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts)
{
Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays");
return null;
}
}
else
{
// The relay is on another device type
if (props.PortNumber > portDevice.NumberOfRelayPorts)
{
Debug.Console(0, "Port Device: {0} does not have enough relays");
return null;
}
}
Relay relay = portDevice.RelayPorts[props.PortNumber];
if (!relay.Registered)
{
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
return new GenericRelayDevice(key, relay);
else
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
}
else
{
return new GenericRelayDevice(key, relay);
}
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
}
*/
}
@@ -258,7 +258,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
#endregion
}
}
}

View File

@@ -130,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

@@ -1,11 +0,0 @@
namespace PepperDash.Essentials.Core.DeviceInfo
{
public class DeviceInfo
{
public string HostName { get; set; }
public string IpAddress { get; set; }
public string MacAddress { get; set; }
public string SerialNumber { get; set; }
public string FirmwareVersion { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.DeviceInfo
{
public class DeviceInfoEventArgs:EventArgs
{
public DeviceInfo DeviceInfo { get; set; }
public DeviceInfoEventArgs()
{
}
public DeviceInfoEventArgs(DeviceInfo devInfo)
{
DeviceInfo = devInfo;
}
}
}

View File

@@ -1,16 +0,0 @@
using System;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceInfo
{
public interface IDeviceInfoProvider:IKeyed
{
DeviceInfo DeviceInfo { get; }
event DeviceInfoChangeHandler DeviceInfoChanged;
void UpdateDeviceInfo();
}
public delegate void DeviceInfoChangeHandler(IKeyed device, DeviceInfoEventArgs args);
}

View File

@@ -6,7 +6,7 @@ using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IHasPowerControl, ITransport, IUiDisplayInfo
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IPower, ITransport, IUiDisplayInfo
{
}

View File

@@ -1,20 +1,8 @@
using System;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{
public interface IHasBranding
{
bool BrandingEnabled { get; }
void InitializeBranding(string roomKey);
}
}
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface IHasBranding
{
bool BrandingEnabled { get; }
void InitializeBranding(string roomKey);
}
}

View File

@@ -1,22 +1,7 @@
using System;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface IHasPhoneDialing
{
BoolFeedback PhoneOffHookFeedback { get; }
StringFeedback CallerIdNameFeedback { get; }
StringFeedback CallerIdNumberFeedback { get; }
void DialPhoneCall(string number);
void EndPhoneCall();
void SendDtmfToPhone(string digit);
}
}
using PepperDash.Essentials.Core;
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface IHasPhoneDialing
{
BoolFeedback PhoneOffHookFeedback { get; }

View File

@@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface ILanguageDefinition
{
string LocaleName { get; set; }
string FriendlyName { get; set; }
bool Enable { get; set; }
List<LanguageLabel> UiLabels { get; set; }
List<LanguageLabel> Sources { get; set; }
List<LanguageLabel> Destinations { get; set; }
List<LanguageLabel> SourceGroupNames { get; set; }
List<LanguageLabel> DestinationGroupNames { get; set; }
List<LanguageLabel> RoomNames { get; set; }
}
}
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface ILanguageDefinition
{
string LocaleName { get; set; }
string FriendlyName { get; set; }
bool Enable { get; set; }
List<LanguageLabel> UiLabels { get; set; }
List<LanguageLabel> Sources { get; set; }
List<LanguageLabel> Destinations { get; set; }
List<LanguageLabel> SourceGroupNames { get; set; }
List<LanguageLabel> DestinationGroupNames { get; set; }
List<LanguageLabel> RoomNames { get; set; }
}
}

View File

@@ -1,25 +0,0 @@
using System;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface ILanguageProvider
{
ILanguageDefinition CurrentLanguage { get; set; }
event EventHandler CurrentLanguageChanged;
}
}
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public interface ILanguageProvider
{
ILanguageDefinition CurrentLanguage { get; set; }
event EventHandler CurrentLanguageChanged;
}
}

View File

@@ -8,9 +8,11 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
/// </summary>
public interface IMobileControl : IKeyed
{
void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
void CreateMobileControlRoomBridge(EssentialsRoomBase room);
void LinkSystemMonitorToAppServer();
}
/// <summary>
@@ -20,16 +22,10 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
event EventHandler<EventArgs> UserCodeChanged;
event EventHandler<EventArgs> UserPromptedForCode;
event EventHandler<EventArgs> ClientJoined;
string UserCode { get; }
string QrCodeUrl { get; }
string QrCodeChecksum { get; }
string McServerUrl { get; }
string RoomName { get; }

View File

@@ -1,5 +1,5 @@
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core
/// <summary>
///
/// </summary>
public interface INumericKeypad:IKeyed
public interface INumericKeypad
{
void Digit0(bool pressRelease);
void Digit1(bool pressRelease);

View File

@@ -14,64 +14,35 @@ using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the ability to power a device on and off
///
/// </summary>
[Obsolete("Will be replaced by IHasPowerControlWithFeedback")]
public interface IPower
{
void PowerOn();
void PowerOff();
void PowerToggle();
BoolFeedback PowerIsOnFeedback { get; }
BoolFeedback PowerIsOnFeedback { get; }
}
/// <summary>
/// Adds feedback for current power state
/// </summary>
public interface IHasPowerControlWithFeedback : IHasPowerControl
{
BoolFeedback PowerIsOnFeedback { get; }
}
/// <summary>
/// Defines the ability to power a device on and off
/// </summary>
public interface IHasPowerControl
{
void PowerOn();
void PowerOff();
void PowerToggle();
}
/// <summary>
///
/// </summary>
public static class IHasPowerControlExtensions
public static class IPowerExtensions
{
public static void LinkButtons(this IHasPowerControl dev, BasicTriList triList)
public static void LinkButtons(this IPower dev, BasicTriList triList)
{
triList.SetSigFalseAction(101, dev.PowerOn);
triList.SetSigFalseAction(102, dev.PowerOff);
triList.SetSigFalseAction(103, dev.PowerToggle);
var fbdev = dev as IHasPowerControlWithFeedback;
if (fbdev != null)
{
fbdev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
}
dev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
}
public static void UnlinkButtons(this IHasPowerControl dev, BasicTriList triList)
public static void UnlinkButtons(this IPower dev, BasicTriList triList)
{
triList.ClearBoolSigAction(101);
triList.ClearBoolSigAction(102);
triList.ClearBoolSigAction(103);
var fbdev = dev as IHasPowerControlWithFeedback;
if (fbdev != null)
{
fbdev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
}
dev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
}
}
}

View File

@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
bool HasDpad { get; }
PepperDash.Essentials.Core.Presets.DevicePresetsModel TvPresets { get; }
PepperDash.Essentials.Core.Presets.DevicePresetsModel PresetsModel { get; }
void LoadPresets(string filePath);
void DvrList(bool pressRelease);

View File

@@ -1,9 +0,0 @@
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public interface ITvPresetsProvider
{
DevicePresetsModel TvPresets { get; }
}
}

View File

@@ -1,25 +0,0 @@
using System;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{
public class LanguageLabel
{
public string Key { get; set; }
public string Description { get; set; }
public string DisplayText { get; set; }
public uint JoinNumber { get; set; }
}
}
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
{
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
public class LanguageLabel
{
public string Key { get; set; }
public string Description { get; set; }
public string DisplayText { get; set; }
public uint JoinNumber { get; set; }
}
}

View File

@@ -83,13 +83,13 @@ namespace PepperDash.Essentials.Core
/// <returns></returns>
public static object GetPropertyByName(string deviceObjectPath, string propertyName)
{
var dev = FindObjectOnPath(deviceObjectPath);
if(dev == null)
var obj = FindObjectOnPath(deviceObjectPath);
if(obj == null)
return "{ \"error\":\"No Device\"}";
object prop = dev.GetType().GetCType().GetProperty(propertyName).GetValue(dev, null);
// var prop = t.GetProperty(propertyName);
CType t = obj.GetType();
var prop = t.GetProperty(propertyName);
if (prop != null)
{
return prop;

View File

@@ -1,355 +1,342 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public static class DeviceManager
{
public static event EventHandler<EventArgs> AllDevicesActivated;
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
//public static List<Device> Devices { get { return _Devices; } }
//static List<Device> _Devices = new List<Device>();
static readonly Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Returns a copy of all the devices in a list
/// </summary>
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
public static bool AddDeviceEnabled;
public static void Initialize(CrestronControlSystem cs)
{
AddDeviceEnabled = true;
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
}
/// <summary>
/// Calls activate steps on all Device class items
/// </summary>
public static void ActivateAll()
{
try
{
DeviceCriticalSection.Enter();
AddDeviceEnabled = false;
// PreActivate all devices
foreach (var d in Devices.Values)
{
try
{
if (d is Device)
(d as Device).PreActivate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
}
}
// Activate all devices
foreach (var d in Devices.Values)
{
try
{
if (d is Device)
(d as Device).Activate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
}
}
// PostActivate all devices
foreach (var d in Devices.Values)
{
try
{
if (d is Device)
(d as Device).PostActivate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
}
}
OnAllDevicesActivated();
}
finally
{
DeviceCriticalSection.Leave();
}
}
private static void OnAllDevicesActivated()
{
var handler = AllDevicesActivated;
if (handler != null)
{
handler(null, new EventArgs());
}
}
/// <summary>
/// Calls activate on all Device class items
/// </summary>
public static void DeactivateAll()
{
try
{
DeviceCriticalSection.Enter();
foreach (var d in Devices.Values.OfType<Device>())
{
d.Deactivate();
}
}
finally
{
DeviceCriticalSection.Leave();
}
}
//static void ListMethods(string devKey)
//{
// var dev = GetDeviceForKey(devKey);
// if(dev != null)
// {
// var type = dev.GetType().GetCType();
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
// var sb = new StringBuilder();
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
// foreach (var m in methods)
// {
// sb.Append(string.Format("{0}(", m.Name));
// var pars = m.GetParameters();
// foreach (var p in pars)
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
// sb.AppendLine(")");
// }
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
// }
//}
private static void ListDevices(string s)
{
Debug.Console(0, "{0} Devices registered with Device Manager:", Devices.Count);
var sorted = Devices.Values.ToList();
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
foreach (var d in sorted)
{
var name = d is IKeyName ? (d as IKeyName).Name : "---";
Debug.Console(0, " [{0}] {1}", d.Key, name);
}
}
private static void ListDeviceFeedbacks(string devKey)
{
var dev = GetDeviceForKey(devKey);
if (dev == null)
{
Debug.Console(0, "Device '{0}' not found", devKey);
return;
}
var statusDev = dev as IHasFeedback;
if (statusDev == null)
{
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
return;
}
statusDev.DumpFeedbacksToConsole(true);
}
//static void ListDeviceCommands(string devKey)
//{
// var dev = GetDeviceForKey(devKey);
// if (dev == null)
// {
// Debug.Console(0, "Device '{0}' not found", devKey);
// return;
// }
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
//}
private static void ListDeviceCommStatuses(string input)
{
var sb = new StringBuilder();
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
{
sb.Append(string.Format("{0}: {1}\r", dev,
dev.CommunicationMonitor.Status));
}
CrestronConsole.ConsoleCommandResponse(sb.ToString());
}
//static void DoDeviceCommand(string command)
//{
// Debug.Console(0, "Not yet implemented. Stay tuned");
//}
public static void AddDevice(IKeyed newDev)
{
try
{
if (!DeviceCriticalSection.TryEnter())
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Currently unable to add devices to Device Manager. Please try again");
return;
}
// Check for device with same key
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
////// If it exists, remove or warn??
//if (existingDevice != null)
if (!AddDeviceEnabled)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "All devices have been activated. Adding new devices is not allowed.");
return;
}
if (Devices.ContainsKey(newDev.Key))
{
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
return;
}
Devices.Add(newDev.Key, newDev);
//if (!(_Devices.Contains(newDev)))
// _Devices.Add(newDev);
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
{
try
{
if (!DeviceCriticalSection.TryEnter())
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"Currently unable to add devices to Device Manager. Please try again");
return;
}
if (!AddDeviceEnabled)
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"All devices have been activated. Adding new devices is not allowed.");
return;
}
foreach (var dev in devicesToAdd)
{
try
{
Devices.Add(dev.Key, dev);
}
catch (ArgumentException ex)
{
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
dev.Key, ex.Message, ex.StackTrace);
}
}
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static void RemoveDevice(IKeyed newDev)
{
try
{
DeviceCriticalSection.Enter();
if (newDev == null)
return;
if (Devices.ContainsKey(newDev.Key))
Devices.Remove(newDev.Key);
//if (_Devices.Contains(newDev))
// _Devices.Remove(newDev);
else
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static IEnumerable<string> GetDeviceKeys()
{
//return _Devices.Select(d => d.Key).ToList();
return Devices.Keys;
}
public static IEnumerable<IKeyed> GetDevices()
{
//return _Devices.Select(d => d.Key).ToList();
return Devices.Values;
}
public static IKeyed GetDeviceForKey(string key)
{
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
if (key != null && Devices.ContainsKey(key))
return Devices[key];
return null;
}
/// <summary>
/// Console handler that simulates com port data receive
/// </summary>
/// <param name="s"></param>
public static void SimulateComReceiveOnDevice(string s)
{
// devcomsim:1 xyzabc
var match = Regex.Match(s, @"(\S*)\s*(.*)");
if (match.Groups.Count < 3)
{
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
return;
}
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
var com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
if (com == null)
{
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
return;
}
com.SimulateReceive(match.Groups[2].Value);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public static class DeviceManager
{
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
//public static List<Device> Devices { get { return _Devices; } }
//static List<Device> _Devices = new List<Device>();
static readonly Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Returns a copy of all the devices in a list
/// </summary>
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
public static bool AddDeviceEnabled;
public static void Initialize(CrestronControlSystem cs)
{
AddDeviceEnabled = true;
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
}
/// <summary>
/// Calls activate steps on all Device class items
/// </summary>
public static void ActivateAll()
{
try
{
DeviceCriticalSection.Enter();
AddDeviceEnabled = false;
// PreActivate all devices
foreach (var d in Devices.Values)
{
try
{
if (d is Device)
(d as Device).PreActivate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
}
}
// Activate all devices
foreach (var d in Devices.Values)
{
try
{
if (d is Device)
(d as Device).Activate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
}
}
// PostActivate all devices
foreach (var d in Devices.Values)
{
try
{
if (d is Device)
(d as Device).PostActivate();
}
catch (Exception e)
{
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
}
}
}
finally
{
DeviceCriticalSection.Leave();
}
}
/// <summary>
/// Calls activate on all Device class items
/// </summary>
public static void DeactivateAll()
{
try
{
DeviceCriticalSection.Enter();
foreach (var d in Devices.Values.OfType<Device>())
{
d.Deactivate();
}
}
finally
{
DeviceCriticalSection.Leave();
}
}
//static void ListMethods(string devKey)
//{
// var dev = GetDeviceForKey(devKey);
// if(dev != null)
// {
// var type = dev.GetType().GetCType();
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
// var sb = new StringBuilder();
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
// foreach (var m in methods)
// {
// sb.Append(string.Format("{0}(", m.Name));
// var pars = m.GetParameters();
// foreach (var p in pars)
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
// sb.AppendLine(")");
// }
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
// }
//}
private static void ListDevices(string s)
{
Debug.Console(0, "{0} Devices registered with Device Manager:", Devices.Count);
var sorted = Devices.Values.ToList();
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
foreach (var d in sorted)
{
var name = d is IKeyName ? (d as IKeyName).Name : "---";
Debug.Console(0, " [{0}] {1}", d.Key, name);
}
}
private static void ListDeviceFeedbacks(string devKey)
{
var dev = GetDeviceForKey(devKey);
if (dev == null)
{
Debug.Console(0, "Device '{0}' not found", devKey);
return;
}
var statusDev = dev as IHasFeedback;
if (statusDev == null)
{
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
return;
}
statusDev.DumpFeedbacksToConsole(true);
}
//static void ListDeviceCommands(string devKey)
//{
// var dev = GetDeviceForKey(devKey);
// if (dev == null)
// {
// Debug.Console(0, "Device '{0}' not found", devKey);
// return;
// }
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
//}
private static void ListDeviceCommStatuses(string input)
{
var sb = new StringBuilder();
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
{
sb.Append(string.Format("{0}: {1}\r", dev,
dev.CommunicationMonitor.Status));
}
CrestronConsole.ConsoleCommandResponse(sb.ToString());
}
//static void DoDeviceCommand(string command)
//{
// Debug.Console(0, "Not yet implemented. Stay tuned");
//}
public static void AddDevice(IKeyed newDev)
{
try
{
if (!DeviceCriticalSection.TryEnter())
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Currently unable to add devices to Device Manager. Please try again");
return;
}
// Check for device with same key
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
////// If it exists, remove or warn??
//if (existingDevice != null)
if (!AddDeviceEnabled)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "All devices have been activated. Adding new devices is not allowed.");
return;
}
if (Devices.ContainsKey(newDev.Key))
{
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
return;
}
Devices.Add(newDev.Key, newDev);
//if (!(_Devices.Contains(newDev)))
// _Devices.Add(newDev);
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
{
try
{
if (!DeviceCriticalSection.TryEnter())
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"Currently unable to add devices to Device Manager. Please try again");
return;
}
if (!AddDeviceEnabled)
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"All devices have been activated. Adding new devices is not allowed.");
return;
}
foreach (var dev in devicesToAdd)
{
try
{
Devices.Add(dev.Key, dev);
}
catch (ArgumentException ex)
{
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
dev.Key, ex.Message, ex.StackTrace);
}
}
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static void RemoveDevice(IKeyed newDev)
{
try
{
DeviceCriticalSection.Enter();
if (newDev == null)
return;
if (Devices.ContainsKey(newDev.Key))
Devices.Remove(newDev.Key);
//if (_Devices.Contains(newDev))
// _Devices.Remove(newDev);
else
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
}
finally
{
DeviceCriticalSection.Leave();
}
}
public static IEnumerable<string> GetDeviceKeys()
{
//return _Devices.Select(d => d.Key).ToList();
return Devices.Keys;
}
public static IEnumerable<IKeyed> GetDevices()
{
//return _Devices.Select(d => d.Key).ToList();
return Devices.Values;
}
public static IKeyed GetDeviceForKey(string key)
{
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
if (key != null && Devices.ContainsKey(key))
return Devices[key];
return null;
}
/// <summary>
/// Console handler that simulates com port data receive
/// </summary>
/// <param name="s"></param>
public static void SimulateComReceiveOnDevice(string s)
{
// devcomsim:1 xyzabc
var match = Regex.Match(s, @"(\S*)\s*(.*)");
if (match.Groups.Count < 3)
{
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
return;
}
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
var com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
if (com == null)
{
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
return;
}
com.SimulateReceive(match.Groups[2].Value);
}
/// <summary>
@@ -360,9 +347,9 @@ namespace PepperDash.Essentials.Core
{
var device = GetDeviceForKey(s);
if (device == null) return;
var inputPorts = ((device as IRoutingInputs) != null) ? (device as IRoutingInputs).InputPorts : null;
var outputPorts = ((device as IRoutingOutputs) != null) ? (device as IRoutingOutputs).OutputPorts : null;
if (device == null) return;
var inputPorts = (device as IRoutingInputsOutputs).InputPorts;
var outputPorts = (device as IRoutingInputsOutputs).OutputPorts;
if (inputPorts != null)
{
Debug.Console(0, "Device {0} has {1} Input Ports:", s, inputPorts.Count);
@@ -379,82 +366,82 @@ namespace PepperDash.Essentials.Core
Debug.Console(0, "{0}", routingOutputPort.Key);
}
}
}
/// <summary>
/// Attempts to set the debug level of a device
/// </summary>
/// <param name="s"></param>
public static void SetDeviceStreamDebugging(string s)
{
var args = s.Split(' ');
var deviceKey = args[0];
var setting = args[1];
var timeout= String.Empty;
if (args.Length >= 3)
{
timeout = args[2];
}
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
if (device == null)
{
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
return;
}
eStreamDebuggingSetting debugSetting;
try
{
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
}
catch
{
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
return;
}
if (!string.IsNullOrEmpty(timeout))
{
try
{
var min = Convert.ToUInt32(timeout);
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
}
catch (Exception e)
{
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
}
}
else
{
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
}
}
/// <summary>
/// Sets stream debugging settings to off for all devices
/// </summary>
public static void DisableAllDeviceStreamDebugging()
{
foreach (var device in AllDevices)
{
var streamDevice = device as IStreamDebugging;
if (streamDevice != null)
{
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
}
}
}
}
}
/// <summary>
/// Attempts to set the debug level of a device
/// </summary>
/// <param name="s"></param>
public static void SetDeviceStreamDebugging(string s)
{
var args = s.Split(' ');
var deviceKey = args[0];
var setting = args[1];
var timeout= String.Empty;
if (args.Length >= 3)
{
timeout = args[2];
}
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
if (device == null)
{
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
return;
}
eStreamDebuggingSetting debugSetting;
try
{
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
}
catch
{
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
return;
}
if (!string.IsNullOrEmpty(timeout))
{
try
{
var min = Convert.ToUInt32(timeout);
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
}
catch (Exception e)
{
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
}
}
else
{
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
}
}
/// <summary>
/// Sets stream debugging settings to off for all devices
/// </summary>
public static void DisableAllDeviceStreamDebugging()
{
foreach (var device in AllDevices)
{
var streamDevice = device as IStreamDebugging;
if (streamDevice != null)
{
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
}
}
}
}
}

View File

@@ -7,7 +7,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.Devices
namespace PepperDash_Essentials_Core.Devices
{
public class GenericIrController: EssentialsBridgeableDevice
{

View File

@@ -1,17 +0,0 @@
using System.Collections.Generic;
namespace PepperDash.Essentials.Core
{
public interface IHasDspPresets
{
List<IDspPreset> Presets { get; }
void RecallPreset(IDspPreset preset);
}
public interface IDspPreset
{
string Name { get; }
}
}

View File

@@ -20,13 +20,10 @@ namespace PepperDash.Essentials.Core
public IrOutputPortController IrPort { get; private set; }
public ushort IrPulseTime { get; set; }
[Obsolete("This property will be removed in version 2.0.0")]
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
protected Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
}
protected override Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
}
protected override Func<bool> IsCoolingDownFeedbackFunc
{
get { return () => _IsCoolingDown; }
@@ -36,7 +33,7 @@ namespace PepperDash.Essentials.Core
get { return () => _IsWarmingUp; }
}
bool _PowerIsOn;
bool _PowerIsOn;
bool _IsWarmingUp;
bool _IsCoolingDown;
@@ -46,14 +43,11 @@ namespace PepperDash.Essentials.Core
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
DeviceManager.AddDevice(IrPort);
PowerIsOnFeedback = new BoolFeedback(PowerIsOnFeedbackFunc);
PowerIsOnFeedback.OutputChange += (o, a) =>
{
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
if (_PowerIsOn) StartWarmingTimer();
else StartCoolingTimer();
};
PowerIsOnFeedback.OutputChange += (o, a) => {
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
if (_PowerIsOn) StartWarmingTimer();
else StartCoolingTimer();
};
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
@@ -116,21 +110,21 @@ namespace PepperDash.Essentials.Core
public override void PowerOn()
{
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
_PowerIsOn = true;
PowerIsOnFeedback.FireUpdate();
_PowerIsOn = true;
PowerIsOnFeedback.FireUpdate();
}
public override void PowerOff()
{
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
}
public override void PowerToggle()
{
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
}

View File

@@ -1,118 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IPower
{
public event SourceInfoChangeHandler CurrentSourceChange;
public string CurrentSourceInfoKey { get; set; }
public SourceListItem CurrentSourceInfo
{
get
{
return _CurrentSourceInfo;
}
set
{
if (value == _CurrentSourceInfo) return;
var handler = CurrentSourceChange;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
_CurrentSourceInfo = value;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
}
}
SourceListItem _CurrentSourceInfo;
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
public BoolFeedback IsWarmingUpFeedback { get; private set; }
[Obsolete("This property will be removed in version 2.0.0")]
public abstract BoolFeedback PowerIsOnFeedback { get; protected set; }
public UsageTracking UsageTracker { get; set; }
public uint WarmupTime { get; set; }
public uint CooldownTime { get; set; }
/// <summary>
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
/// by concrete sub-classes
/// </summary>
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
protected CTimer WarmupTimer;
protected CTimer CooldownTimer;
#region IRoutingInputs Members
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
#endregion
protected DisplayBase(string key, string name)
: base(key, name)
{
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
InputPorts = new RoutingPortCollection<RoutingInputPort>();
}
public abstract void PowerOn();
public abstract void PowerOff();
public abstract void PowerToggle();
public virtual FeedbackCollection<Feedback> Feedbacks
{
get
{
return new FeedbackCollection<Feedback>
{
IsCoolingDownFeedback,
IsWarmingUpFeedback
};
}
}
public abstract void ExecuteSwitch(object selector);
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge)
{
var inputNumber = 0;
var inputKeys = new List<string>();
var joinMap = new DisplayControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking
{
public event SourceInfoChangeHandler CurrentSourceChange;
public string CurrentSourceInfoKey { get; set; }
public SourceListItem CurrentSourceInfo
{
get
{
return _CurrentSourceInfo;
}
set
{
if (value == _CurrentSourceInfo) return;
var handler = CurrentSourceChange;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.WillChange);
_CurrentSourceInfo = value;
if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange);
}
}
SourceListItem _CurrentSourceInfo;
public BoolFeedback PowerIsOnFeedback { get; protected set; }
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
public BoolFeedback IsWarmingUpFeedback { get; private set; }
public UsageTracking UsageTracker { get; set; }
public uint WarmupTime { get; set; }
public uint CooldownTime { get; set; }
/// <summary>
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
/// by concrete sub-classes
/// </summary>
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
protected CTimer WarmupTimer;
protected CTimer CooldownTimer;
#region IRoutingInputs Members
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
#endregion
protected DisplayBase(string key, string name)
: base(key, name)
{
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
InputPorts = new RoutingPortCollection<RoutingInputPort>();
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
}
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
{
if (UsageTracker != null)
{
if (PowerIsOnFeedback.BoolValue)
UsageTracker.StartDeviceUsage();
else
UsageTracker.EndDeviceUsage();
}
}
public abstract void PowerOn();
public abstract void PowerOff();
public abstract void PowerToggle();
public virtual FeedbackCollection<Feedback> Feedbacks
{
get
{
return new FeedbackCollection<Feedback>
{
PowerIsOnFeedback,
IsCoolingDownFeedback,
IsWarmingUpFeedback
};
}
}
public abstract void ExecuteSwitch(object selector);
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
EiscApiAdvanced bridge)
{
var inputNumber = 0;
var inputKeys = new List<string>();
var joinMap = new DisplayControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
if (bridge != null)
@@ -124,198 +137,163 @@ namespace PepperDash.Essentials.Core
Debug.Console(0,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
var commMonitor = displayDevice as ICommunicationMonitor;
if (commMonitor != null)
{
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
}
var inputNumberFeedback = new IntFeedback(() => inputNumber);
// Two way feedbacks
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
if (twoWayDisplay != null)
{
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
}
// Power Off
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOff();
});
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
if (twoWayDisplayDevice != null)
{
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (!a.BoolValue)
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
}
else
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
}
};
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
}
// PowerOn
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOn();
});
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
{
if (i < joinMap.InputNamesOffset.JoinSpan)
{
inputKeys.Add(displayDevice.InputPorts[i].Key);
var tempKey = inputKeys.ElementAt(i);
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
}
else
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
}
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
{
if (a == 0)
{
displayDevice.PowerOff();
inputNumber = 0;
}
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
{
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
inputNumber = a;
}
else if (a == 102)
{
displayDevice.PowerToggle();
}
if (twoWayDisplay != null)
inputNumberFeedback.FireUpdate();
});
var volumeDisplay = displayDevice as IBasicVolumeControls;
if (volumeDisplay == null) return;
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
if (volumeDisplayWithFeedback == null) return;
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
}
}
/// <summary>
///
/// </summary>
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
{
public StringFeedback CurrentInputFeedback { get; private set; }
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
public static MockDisplay DefaultDisplay
{
get
{
if (_DefaultDisplay == null)
_DefaultDisplay = new MockDisplay("default", "Default Display");
return _DefaultDisplay;
}
}
static MockDisplay _DefaultDisplay;
public TwoWayDisplayBase(string key, string name)
: base(key, name)
{
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
WarmupTime = 7000;
CooldownTime = 15000;
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
Feedbacks.Add(CurrentInputFeedback);
Feedbacks.Add(PowerIsOnFeedback);
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
}
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
{
if (UsageTracker != null)
{
if (PowerIsOnFeedback.BoolValue)
UsageTracker.StartDeviceUsage();
else
UsageTracker.EndDeviceUsage();
}
}
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
protected void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
}
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
var commMonitor = displayDevice as ICommunicationMonitor;
if (commMonitor != null)
{
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
}
var inputNumberFeedback = new IntFeedback(() => inputNumber);
// Two way feedbacks
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
if (twoWayDisplay != null)
{
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
}
// Power Off
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOff();
});
displayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
{
if (!a.BoolValue)
{
inputNumber = 102;
inputNumberFeedback.FireUpdate();
}
else
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
}
};
displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
// PowerOn
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
{
inputNumber = 0;
inputNumberFeedback.FireUpdate();
displayDevice.PowerOn();
});
displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
{
if (i < joinMap.InputNamesOffset.JoinSpan)
{
inputKeys.Add(displayDevice.InputPorts[i].Key);
var tempKey = inputKeys.ElementAt(i);
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
}
else
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
}
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
{
if (a == 0)
{
displayDevice.PowerOff();
inputNumber = 0;
}
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
{
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
inputNumber = a;
}
else if (a == 102)
{
displayDevice.PowerToggle();
}
if (twoWayDisplay != null)
inputNumberFeedback.FireUpdate();
});
var volumeDisplay = displayDevice as IBasicVolumeControls;
if (volumeDisplay == null) return;
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
if (volumeDisplayWithFeedback == null) return;
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
}
}
/// <summary>
///
/// </summary>
public abstract class TwoWayDisplayBase : DisplayBase
{
public StringFeedback CurrentInputFeedback { get; private set; }
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
public static MockDisplay DefaultDisplay
{
get
{
if (_DefaultDisplay == null)
_DefaultDisplay = new MockDisplay("default", "Default Display");
return _DefaultDisplay;
}
}
static MockDisplay _DefaultDisplay;
public TwoWayDisplayBase(string key, string name)
: base(key, name)
{
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
WarmupTime = 7000;
CooldownTime = 15000;
Feedbacks.Add(CurrentInputFeedback);
}
}
}

View File

@@ -67,13 +67,13 @@ namespace PepperDash.Essentials.Core
/// <returns></returns>
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
}
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
if(FactoryMethods.ContainsKey(typeName))
{

View File

@@ -3,30 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core
{
public class IsReadyEventArgs : EventArgs
{
public bool IsReady { get; set; }
public IsReadyEventArgs(bool data)
{
IsReady = data;
}
}
public interface IHasReady
{
event EventHandler<IsReadyEventArgs> IsReadyEvent;
bool IsReady { get; }
}
}
namespace PepperDash_Essentials_Core
{
[Obsolete("Use PepperDash.Essentials.Core")]
public class IsReadyEventArgs : EventArgs
{
public bool IsReady { get; set; }
@@ -37,7 +16,6 @@ namespace PepperDash_Essentials_Core
}
}
[Obsolete("Use PepperDash.Essentials.Core")]
public interface IHasReady
{
event EventHandler<IsReadyEventArgs> IsReadyEvent;

View File

@@ -1,150 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core.Fusion
{
public class EssentialsHuddleSpaceRoomFusionRoomJoinMap : JoinMapBaseAdvanced
{
// Processor Attributes
[JoinName("ProcessorIp1")]
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorIp2")]
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorGateway")]
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorHostname")]
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorDomain")]
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorDns1")]
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorDns2")]
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorMac1")]
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorMac2")]
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorNetMask1")]
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorNetMask2")]
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorFirmware")]
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProgramNameStart")]
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("ProcessorReboot")]
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
// Volume Controls
[JoinName("VolumeFader1")]
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
// Codec Info
[JoinName("VcCodecInCall")]
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
[JoinName("VcCodecOnline")]
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
[JoinName("VcCodecIpAddress")]
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
[JoinName("VcCodecIpPort")]
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
// Source Attributes
[JoinName("Display1CurrentSourceName")]
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
// Device Online Status
[JoinName("TouchpanelOnlineStart")]
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
[JoinName("XpanelOnlineStart")]
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
[JoinName("DisplayOnlineStart")]
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
[JoinName("Display1LaptopSourceStart")]
public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
[JoinName("Display1DiscPlayerSourceStart")]
public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
[JoinName("Display1SetTopBoxSourceStart")]
public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
// Display 1
[JoinName("Display1Start")]
public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart)
: base(joinStart, typeof(EssentialsHuddleSpaceRoomFusionRoomJoinMap))
{
}
/// <summary>
/// Constructor to use when extending this Join map
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
/// <param name="type">Type of the child join map</param>
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type)
{
}
}
}

View File

@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash_Essentials_Core.Gateways
{
public class CenCn2Controller
{
}
}

View File

@@ -10,7 +10,9 @@ using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash_Essentials_Core;
namespace PepperDash.Essentials.Core

View File

@@ -26,8 +26,6 @@ namespace PepperDash.Essentials.Core
public static LicenseManager LicenseManager { get; set; }
public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } }
/// <summary>
/// The file path prefix to the folder containing configuration files
/// </summary>

View File

@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharp.Scheduler;
using PepperDash.Core;
using PepperDash.Essentials.Core.Fusion;
using PepperDash.Essentials.Room.Config;
using Activator = System.Activator;
namespace PepperDash.Essentials.Core
{
@@ -17,17 +14,13 @@ namespace PepperDash.Essentials.Core
/// </summary>
public static class Scheduler
{
private static readonly Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
private static Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
static Scheduler()
{
CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(ListAllEventsForGroup, "ListEventsForGroup",
"Lists all events for the given group", ConsoleAccessLevelEnum.AccessOperator);
}
/// <summary>
@@ -36,26 +29,12 @@ namespace PepperDash.Essentials.Core
/// <param name="groupName"></param>
static void ClearEventsFromGroup(string groupName)
{
if (!EventGroups.ContainsKey(groupName))
{
Debug.Console(0,
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
groupName);
return;
}
var group = EventGroups[groupName];
if (group != null)
{
group.ClearAllEvents();
Debug.Console(0, "[Scheduler]: All events deleted from group '{0}'", groupName);
}
else
Debug.Console(0,
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
groupName);
Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName);
}
static void ListAllEventGroups(string command)
@@ -67,36 +46,10 @@ namespace PepperDash.Essentials.Core
}
}
static void ListAllEventsForGroup(string args)
{
Debug.Console(0, "Getting events for group {0}...", args);
ScheduledEventGroup group;
if (!EventGroups.TryGetValue(args, out group))
{
Debug.Console(0, "Unabled to get event group for key {0}", args);
return;
}
foreach (var evt in group.ScheduledEvents)
{
Debug.Console(0,
@"
****Event key {0}****
Event date/time: {1}
Persistent: {2}
Acknowlegable: {3}
Recurrence: {4}
Recurrence Days: {5}
********************", evt.Key, evt.Value.DateAndTime, evt.Value.Persistent, evt.Value.Acknowledgeable,
evt.Value.Recurrence.Recurrence, evt.Value.Recurrence.RecurrenceDays);
}
}
/// <summary>
/// Adds the event group to the global list
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static void AddEventGroup(ScheduledEventGroup eventGroup)
{
@@ -114,13 +67,6 @@ Recurrence Days: {5}
if(!EventGroups.ContainsKey(eventGroup.Name))
EventGroups.Remove(eventGroup.Name);
}
public static ScheduledEventGroup GetEventGroup(string key)
{
ScheduledEventGroup returnValue;
return EventGroups.TryGetValue(key, out returnValue) ? returnValue : null;
}
}
public static class SchedulerUtilities
@@ -189,90 +135,5 @@ Recurrence Days: {5}
return isMatch;
}
public static bool CheckEventTimeForMatch(ScheduledEvent evnt, DateTime time)
{
return evnt.DateAndTime.Hour == time.Hour && evnt.DateAndTime.Minute == time.Minute;
}
public static bool CheckEventRecurrenceForMatch(ScheduledEvent evnt, ScheduledEventCommon.eWeekDays days)
{
return evnt.Recurrence.RecurrenceDays == days;
}
public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler)
{
if (group == null)
{
Debug.Console(0, "Unable to create event. Group is null");
return;
}
var scheduledEvent = new ScheduledEvent(config.Key, group)
{
Acknowledgeable = config.Acknowledgeable,
Persistent = config.Persistent
};
scheduledEvent.UserCallBack += handler;
scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday);
var eventTime = DateTime.Parse(config.Time);
if (DateTime.Now > eventTime)
{
eventTime = eventTime.AddDays(1);
}
Debug.Console(2, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek,
config.Days);
var dayOfWeekConverted = ConvertDayOfWeek(eventTime);
Debug.Console(1, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted);
while (!dayOfWeekConverted.IsFlagSet(config.Days))
{
eventTime = eventTime.AddDays(1);
dayOfWeekConverted = ConvertDayOfWeek(eventTime);
}
scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime);
scheduledEvent.Recurrence.Weekly(config.Days);
if (config.Enable)
{
scheduledEvent.Enable();
}
else
{
scheduledEvent.Disable();
}
}
private static ScheduledEventCommon.eWeekDays ConvertDayOfWeek(DateTime eventTime)
{
return (ScheduledEventCommon.eWeekDays) Enum.Parse(typeof(ScheduledEventCommon.eWeekDays), eventTime.DayOfWeek.ToString(), true);
}
private static bool IsFlagSet<T>(this T value, T flag) where T : struct
{
CheckIsEnum<T>(true);
var lValue = Convert.ToInt64(value);
var lFlag = Convert.ToInt64(flag);
return (lValue & lFlag) != 0;
}
private static void CheckIsEnum<T>(bool withFlags)
{
if (!typeof(T).IsEnum)
throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
}
}
}

View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Interfaces
{
public interface ILogStrings : IKeyed
{
/// <summary>
/// Defines a class that is capable of logging a string
/// </summary>
void SendToLog(IKeyed device, string logMessage);
}
}

View File

@@ -1,18 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Interfaces
{
public interface ILogStringsWithLevel : IKeyed
{
/// <summary>
/// Defines a class that is capable of logging a string with an int level
/// </summary>
void SendToLog(IKeyed device, Debug.ErrorLogLevel level,string logMessage);
}
}

View File

@@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
return joinMap.ToString();
return joinMap;
}
/// <summary>
@@ -45,33 +45,16 @@ namespace PepperDash.Essentials.Core
/// <returns></returns>
public static Dictionary<string, JoinData> TryGetJoinMapAdvancedForDevice(string joinMapKey)
{
try
{
if (string.IsNullOrEmpty(joinMapKey))
return null;
if (!ConfigReader.ConfigObject.JoinMaps.ContainsKey(joinMapKey))
{
Debug.Console(2, "No Join Map found in config with key: '{0}'", joinMapKey);
return null;
}
Debug.Console(2, "Attempting to load custom join map with key: {0}", joinMapKey);
var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
if (joinMapJToken == null)
return null;
var joinMapData = joinMapJToken.ToObject<Dictionary<string, JoinData>>();
return joinMapData;
}
catch (Exception e)
{
Debug.Console(2, "Error getting join map for key: '{0}'. Error: {1}", joinMapKey, e);
if (string.IsNullOrEmpty(joinMapKey))
return null;
}
var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
if (joinMapSerialzed == null) return null;
var joinMapData = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
return joinMapData;
}
}
@@ -233,10 +216,7 @@ namespace PepperDash.Essentials.Core
}
if (Debug.Level > 0)
{
PrintJoinMapInfo();
}
PrintJoinMapInfo();
}
/// <summary>
@@ -286,7 +266,7 @@ namespace PepperDash.Essentials.Core
@"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.JoinSpan,
String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName,
String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label: join.Value.Metadata.Description,
join.Value.Metadata.JoinType.ToString(),
join.Value.Metadata.JoinCapabilities.ToString());
}
@@ -308,7 +288,7 @@ namespace PepperDash.Essentials.Core
}
else
{
Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
}
}
@@ -347,10 +327,7 @@ namespace PepperDash.Essentials.Core
None = 0,
ToSIMPL = 1,
FromSIMPL = 2,
ToFromSIMPL = ToSIMPL | FromSIMPL,
ToFusion = 4,
FromFusion = 8,
ToFromFusion = ToFusion | FromFusion,
ToFromSIMPL = ToSIMPL | FromSIMPL
}
[Flags]
@@ -363,7 +340,7 @@ namespace PepperDash.Essentials.Core
DigitalAnalog = Digital | Analog,
DigitalSerial = Digital | Serial,
AnalogSerial = Analog | Serial,
DigitalAnalogSerial = Digital | Analog | Serial,
DigitalAnalogSerial = Digital | Analog | Serial
}
/// <summary>
@@ -417,7 +394,7 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
/// Data describing the join. Can be overridden from configuratino
/// Data describing the join. Can be
/// </summary>
public class JoinData
{
@@ -431,11 +408,6 @@ namespace PepperDash.Essentials.Core
/// </summary>
[JsonProperty("joinSpan")]
public uint JoinSpan { get; set; }
/// <summary>
/// Fusion Attribute Name (optional)
/// </summary>
[JsonProperty("attributeName")]
public string AttributeName { get; set; }
}
/// <summary>
@@ -447,10 +419,6 @@ namespace PepperDash.Essentials.Core
private JoinData _data;
public JoinMetadata Metadata { get; set; }
/// <summary>
/// To store some future information as you please
/// </summary>
public object UserObject { get; private set; }
public JoinDataComplete(JoinData data, JoinMetadata metadata)
{
@@ -481,11 +449,6 @@ namespace PepperDash.Essentials.Core
get { return _data.JoinSpan; }
}
public string AttributeName
{
get { return _data.AttributeName; }
}
public void SetCustomJoinData(JoinData customJoinData)
{
_data = customJoinData;

View File

@@ -88,12 +88,8 @@ namespace PepperDash.Essentials.Core.Privacy
else
Debug.Console(0, this, "Unable to add Red LED device");
DeviceManager.AllDevicesActivated += (o, a) =>
{
CheckPrivacyMode();
};
AddPostActivationAction(() => {
CheckPrivacyMode();
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
});

View File

@@ -64,34 +64,30 @@ namespace PepperDash.Essentials.Core
initialStatus = MonitorStatus.InWarning;
prefix = "2:";
}
else if (IsOk.Count() > 0)
else if (InWarning.Count() > 0)
initialStatus = MonitorStatus.IsOk;
else
initialStatus = MonitorStatus.StatusUnknown;
// Build the error message string
if (InError.Count() > 0 || InWarning.Count() > 0)
{
StringBuilder sb = new StringBuilder(prefix);
if (InError.Count() > 0)
{
// Do string splits and joins
sb.Append(string.Format("{0} Errors:", InError.Count()));
foreach (var mon in InError)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
if (InWarning.Count() > 0)
{
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
foreach (var mon in InWarning)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
Message = sb.ToString();
}
else
{
Message = "Room Ok.";
}
if (InError.Count() > 0 || InWarning.Count() > 0)
{
StringBuilder sb = new StringBuilder(prefix);
if (InError.Count() > 0)
{
// Do string splits and joins
sb.Append(string.Format("{0} Errors:", InError.Count()));
foreach (var mon in InError)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
if (InWarning.Count() > 0)
{
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
foreach (var mon in InWarning)
sb.Append(string.Format("{0}, ", mon.Parent.Key));
}
Message = sb.ToString();
}
// Want to fire even if status doesn't change because the message may.
Status = initialStatus;

View File

@@ -1,539 +1,460 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
[ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0}")]
public abstract class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
{
public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; }
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
{
public GlsOccupancySensorBase OccSensor { get; private set; }
protected GlsOccupancySensorBase OccSensor;
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
public BoolFeedback RawOccupancyFeedback { get; private set; }
public BoolFeedback RawOccupancyFeedback { get; private set; }
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
public IntFeedback CurrentTimeoutFeedback { get; private set; }
public IntFeedback CurrentTimeoutFeedback { get; private set; }
public IntFeedback LocalTimoutFeedback { get; private set; }
public IntFeedback LocalTimoutFeedback { get; private set; }
public IntFeedback InternalPhotoSensorValue { get; set; }
public IntFeedback InternalPhotoSensorValue { get; set; }
public IntFeedback ExternalPhotoSensorValue { get; set; }
public IntFeedback ExternalPhotoSensorValue { get; set; }
// Debug properties
public bool InTestMode { get; private set; }
// Debug properties
public bool InTestMode { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
public bool TestRoomIsOccupiedFeedback { get; private set; }
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
}
}
protected GlsOccupancySensorBaseController(string key, DeviceConfig config)
: this(key, config.Name, config)
{
}
protected GlsOccupancySensorBaseController(string key, string name, DeviceConfig config)
: base(key, name)
public Func<bool> RoomIsOccupiedFeedbackFunc
{
var props = config.Properties.ToObject<GlsOccupancySensorPropertiesConfig>();
if (props != null)
get
{
PropertiesConfig = props;
}
else
{
Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig");
}
AddPostActivationAction(() =>
{
OccSensor.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
{
ApplySettingsToSensorFromConfig();
}
};
if (OccSensor.IsOnline)
{
ApplySettingsToSensorFromConfig();
}
});
}
/// <summary>
/// Applies any sensor settings defined in config
/// </summary>
protected virtual void ApplySettingsToSensorFromConfig()
{
Debug.Console(1, this, "Attempting to apply settings to sensor from config");
if (PropertiesConfig.EnablePir != null)
{
Debug.Console(1, this, "EnablePir found, attempting to set value from config");
SetPirEnable((bool)PropertiesConfig.EnablePir);
}
else
{
Debug.Console(1, this, "EnablePir null, no value specified in config");
}
if (PropertiesConfig.EnableLedFlash != null)
{
Debug.Console(1, this, "EnableLedFlash found, attempting to set value from config");
SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash);
}
if (PropertiesConfig.RemoteTimeout != null)
{
Debug.Console(1, this, "RemoteTimeout found, attempting to set value from config");
SetRemoteTimeout((ushort)PropertiesConfig.RemoteTimeout);
}
else
{
Debug.Console(1, this, "RemoteTimeout null, no value specified in config");
}
if (PropertiesConfig.ShortTimeoutState != null)
{
SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState);
}
if (PropertiesConfig.EnableRawStates != null)
{
EnableRawStates((bool)PropertiesConfig.EnableRawStates);
}
if (PropertiesConfig.InternalPhotoSensorMinChange != null)
{
SetInternalPhotoSensorMinChange((ushort)PropertiesConfig.InternalPhotoSensorMinChange);
}
if (PropertiesConfig.ExternalPhotoSensorMinChange != null)
{
SetExternalPhotoSensorMinChange((ushort)PropertiesConfig.ExternalPhotoSensorMinChange);
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
}
}
protected void RegisterGlsOccupancySensorBaseController(GlsOccupancySensorBase occSensor)
{
OccSensor = occSensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
PirSensitivityInVacantStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
PirSensitivityInOccupiedStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
GraceOccupancyDetectedFeedback =
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
OccSensor.BaseEvent += OccSensor_BaseEvent;
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
}
public GlsOccupancySensorBaseController(string key, Func<DeviceConfig, GlsOccupancySensorBase> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
/// <summary>
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
switch (args.EventId)
{
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
PirSensorEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
LedFlashEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
ShortTimeoutEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
PirSensitivityInOccupiedStateFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
PirSensitivityInVacantStateFeedback.FireUpdate();
break;
}
}
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
switch (args.EventId)
{
case GlsOccupancySensorBase.RoomVacantFeedbackEventId:
case GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
RoomIsOccupiedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
CurrentTimeoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
LocalTimoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
GraceOccupancyDetectedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
RawOccupancyFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
InternalPhotoSensorValue.FireUpdate();
break;
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
ExternalPhotoSensorValue.FireUpdate();
break;
}
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
/// <summary>
/// Enables or disables the PIR sensor
/// </summary>
/// <param name="state"></param>
public void SetPirEnable(bool state)
{
Debug.Console(1, this, "Setting EnablePir to: {0}", state);
OccSensor.EnablePir.BoolValue = state;
OccSensor.DisablePir.BoolValue = !state;
}
/// <summary>
/// Enables or disables the LED Flash
/// </summary>
/// <param name="state"></param>
public void SetLedFlashEnable(bool state)
{
OccSensor.EnableLedFlash.BoolValue = state;
OccSensor.DisableLedFlash.BoolValue = !state;
}
/// <summary>
/// Enables or disables short timeout based on state
/// </summary>
/// <param name="state"></param>
public void SetShortTimeoutState(bool state)
{
OccSensor.EnableShortTimeout.BoolValue = state;
OccSensor.DisableShortTimeout.BoolValue = !state;
}
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementPirSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementPirSensitivityInVacantState(bool pressRelease)
{
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
}
/// <summary>
/// Pulse ForceOccupied on the sensor for .5 seconds
/// </summary>
public void ForceOccupied()
{
CrestronInvoke.BeginInvoke((o) =>
{
ForceOccupied(true);
CrestronEnvironment.Sleep(500);
ForceOccupied(false);
});
}
public void ForceOccupied(bool value)
{
OccSensor.ForceOccupied.BoolValue = value;
}
/// <summary>
/// Pulse ForceVacant on the sensor for .5 seconds
/// </summary>
public void ForceVacant()
{
CrestronInvoke.BeginInvoke((o) =>
AddPreActivationAction(() =>
{
ForceVacant(true);
CrestronEnvironment.Sleep(500);
ForceVacant(false);
OccSensor = preActivationFunc(config);
RegisterCrestronGenericBase(OccSensor);
RegisterGlsOdtSensorBaseController(OccSensor);
});
}
}
public void ForceVacant(bool value)
{
OccSensor.ForceVacant.BoolValue = value;
}
public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {}
public void EnableRawStates(bool state)
{
OccSensor.EnableRawStates.BoolValue = state;
}
protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor)
{
OccSensor = occSensor;
public void SetRemoteTimeout(ushort time)
{
Debug.Console(1, this, "Setting RemoteTimout to: {0}", time);
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
OccSensor.RemoteTimeout.UShortValue = time;
}
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
public void SetInternalPhotoSensorMinChange(ushort value)
{
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
}
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
public void SetExternalPhotoSensorMinChange(ushort value)
{
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
}
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
/// <summary>
/// Method to print current occ settings to console.
/// </summary>
public virtual void GetSettings()
{
var dash = new string('*', 50);
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
PirSensitivityInVacantStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
Debug.Console(0, this, "Vacancy Detected: {0}",
OccSensor.VacancyDetectedFeedback.BoolValue);
PirSensitivityInOccupiedStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
Debug.Console(0, this, "Timeout Current: {0} | Local: {1}",
OccSensor.CurrentTimeoutFeedback.UShortValue,
OccSensor.LocalTimeoutFeedback.UShortValue);
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
Debug.Console(0, this, "Short Timeout Enabled: {0}",
OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
Debug.Console(0, this, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}",
OccSensor.PirEnabledFeedback.BoolValue,
OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue,
OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
GraceOccupancyDetectedFeedback =
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
}
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
OccSensor.BaseEvent += OccSensor_BaseEvent;
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
trilist.OnlineStatusChange += (d, args) =>
{
if (args.DeviceOnLine)
{
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
}
};
LinkSingleTechSensorToApi(occController, trilist, joinMap);
LinkDualTechSensorToApi(occController, trilist, joinMap);
}
private static void LinkDualTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
GlsOccupancySensorBaseJoinMap joinMap)
{
var odtOccController = occController as GlsOdtOccupancySensorController;
if (odtOccController == null)
{
return;
}
// OR When Vacated
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
// AND When Vacated
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
// Ultrasonic A Sensor
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
// Ultrasonic B Sensor
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
odtOccController.UltrasonicBEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
// US Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber,
odtOccController.IncrementUsSensitivityInOccupiedState);
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber,
odtOccController.DecrementUsSensitivityInOccupiedState);
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(
trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
// US Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber,
odtOccController.IncrementUsSensitivityInVacantState);
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber,
odtOccController.DecrementUsSensitivityInVacantState);
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(
trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
//Sensor Raw States
odtOccController.RawOccupancyPirFeedback.LinkInputSig(
trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
}
private static void LinkSingleTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
GlsOccupancySensorBaseJoinMap joinMap)
{
// Occupied status
trilist.SetBoolSigAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
trilist.SetBoolSigAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(
trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
// Timouts
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
// LED Flash
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
// Short Timeout
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
// PIR Sensor
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
// PIR Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber,
occController.IncrementPirSensitivityInOccupiedState);
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber,
occController.DecrementPirSensitivityInOccupiedState);
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(
trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
// PIR Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber,
occController.IncrementPirSensitivityInVacantState);
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber,
occController.DecrementPirSensitivityInVacantState);
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(
trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
}
}
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
}
/// <summary>
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
switch (args.EventId)
{
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
PirSensorEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
LedFlashEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
ShortTimeoutEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
PirSensitivityInOccupiedStateFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
PirSensitivityInVacantStateFeedback.FireUpdate();
break;
}
}
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
switch (args.EventId)
{
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId:
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
RoomIsOccupiedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
CurrentTimeoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
LocalTimoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
GraceOccupancyDetectedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
RawOccupancyFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
InternalPhotoSensorValue.FireUpdate();
break;
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
ExternalPhotoSensorValue.FireUpdate();
break;
}
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
/// <summary>
/// Enables or disables the PIR sensor
/// </summary>
/// <param name="state"></param>
public void SetPirEnable(bool state)
{
if (state)
{
OccSensor.EnablePir.BoolValue = state;
OccSensor.DisablePir.BoolValue = !state;
}
else
{
OccSensor.EnablePir.BoolValue = state;
OccSensor.DisablePir.BoolValue = !state;
}
}
/// <summary>
/// Enables or disables the LED Flash
/// </summary>
/// <param name="state"></param>
public void SetLedFlashEnable(bool state)
{
if (state)
{
OccSensor.EnableLedFlash.BoolValue = state;
OccSensor.DisableLedFlash.BoolValue = !state;
}
else
{
OccSensor.EnableLedFlash.BoolValue = state;
OccSensor.DisableLedFlash.BoolValue = !state;
}
}
/// <summary>
/// Enables or disables short timeout based on state
/// </summary>
/// <param name="state"></param>
public void SetShortTimeoutState(bool state)
{
if (state)
{
OccSensor.EnableShortTimeout.BoolValue = state;
OccSensor.DisableShortTimeout.BoolValue = !state;
}
else
{
OccSensor.EnableShortTimeout.BoolValue = state;
OccSensor.DisableShortTimeout.BoolValue = !state;
}
}
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementPirSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementPirSensitivityInVacantState(bool pressRelease)
{
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
}
public void ForceOccupied()
{
OccSensor.ForceOccupied.BoolValue = true;
}
public void ForceVacant()
{
OccSensor.ForceVacant.BoolValue = true;
}
public void EnableRawStates(bool state)
{
OccSensor.EnableRawStates.BoolValue = state;
}
public void SetRemoteTimeout(ushort time)
{
OccSensor.RemoteTimeout.UShortValue = time;
}
public void SetInternalPhotoSensorMinChange(ushort value)
{
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
}
public void SetExternalPhotoSensorMinChange(ushort value)
{
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
}
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
#region Single and Dual Sensor Stuff
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
trilist.OnlineStatusChange += (d, args) =>
{
if (args.DeviceOnLine)
{
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
}
};
// Occupied status
trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
// Timouts
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
// LED Flash
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
// Short Timeout
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
// PIR Sensor
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
// PIR Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState);
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState);
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
// PIR Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState);
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState);
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
#endregion
#region Dual Technology Sensor Stuff
var odtOccController = occController as GlsOdtOccupancySensorController;
if (odtOccController == null) return;
// OR When Vacated
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
// AND When Vacated
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
// Ultrasonic A Sensor
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
// Ultrasonic B Sensor
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
// US Sensitivity in Occupied State
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState);
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState);
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
// US Sensitivity in Vacant State
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState);
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState);
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
//Sensor Raw States
odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
#endregion
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
#region PreActivation
private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
var branchId = control.ControlPortNumber;
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
return new GlsOirCCn(cresnetId, Global.ControlSystem);
}
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
if (cresnetBridge != null)
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<GlsOccupancySensorBaseController>
{
public GlsOccupancySensorBaseControllerFactory()
{
TypeNames = new List<string>() { "glsoirccn" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc);
}
}
}
}

View File

@@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines configuration properties for Crestron GLS series occupancy sensors
/// </summary>
public class GlsOccupancySensorPropertiesConfig
{
// Single Technology Sensors (PIR): GlsOccupancySensorBase
[JsonProperty("enablePir")]
public bool? EnablePir { get; set; }
[JsonProperty("enableLedFlash")]
public bool? EnableLedFlash { get; set; }
[JsonProperty("shortTimeoutState")]
public bool? ShortTimeoutState { get; set; }
[JsonProperty("enableRawStates")]
public bool? EnableRawStates { get; set; }
[JsonProperty("remoteTimeout")]
public ushort? RemoteTimeout { get; set; }
[JsonProperty("internalPhotoSensorMinChange")]
public ushort? InternalPhotoSensorMinChange { get; set; }
[JsonProperty("externalPhotoSensorMinChange")]
public ushort? ExternalPhotoSensorMinChange { get; set; }
// Dual Technology Sensors: GlsOdtCCn
[JsonProperty("enableUsA")]
public bool? EnableUsA { get; set; }
[JsonProperty("enableUsB")]
public bool? EnableUsB { get; set; }
[JsonProperty("orWhenVacatedState")]
public bool? OrWhenVacatedState { get; set; }
[JsonProperty("andWhenVacatedState")]
public bool? AndWhenVacatedState { get; set; }
}
}

View File

@@ -1,266 +1,183 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Core
{
[Description("Wrapper class for Dual Technology GLS Occupancy Sensors")]
[ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0,\"enableUsA\": true,\"enableUsB\": true,\"orWhenVacatedState\": true}")]
[Description("Wrapper class for Dual Technology GLS Occupancy Sensors")]
public class GlsOdtOccupancySensorController : GlsOccupancySensorBaseController
{
private GlsOdtCCn _occSensor;
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
DeviceConfig config)
: base(key, config.Name, config)
{
AddPreActivationAction(() =>
{
_occSensor = preActivationFunc(config);
RegisterCrestronGenericBase(_occSensor);
RegisterGlsOccupancySensorBaseController(_occSensor);
AndWhenVacatedFeedback = new BoolFeedback(() => _occSensor.AndWhenVacatedFeedback.BoolValue);
OrWhenVacatedFeedback = new BoolFeedback(() => _occSensor.OrWhenVacatedFeedback.BoolValue);
UltrasonicAEnabledFeedback = new BoolFeedback(() => _occSensor.UsAEnabledFeedback.BoolValue);
UltrasonicBEnabledFeedback = new BoolFeedback(() => _occSensor.UsBEnabledFeedback.BoolValue);
RawOccupancyPirFeedback = new BoolFeedback(() => _occSensor.RawOccupancyPirFeedback.BoolValue);
RawOccupancyUsFeedback = new BoolFeedback(() => _occSensor.RawOccupancyUsFeedback.BoolValue);
UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => _occSensor.UsSensitivityInVacantStateFeedback.UShortValue);
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => _occSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
});
}
protected override void ApplySettingsToSensorFromConfig()
{
base.ApplySettingsToSensorFromConfig();
if (PropertiesConfig.EnableUsA != null)
{
Debug.Console(1, this, "EnableUsA found, attempting to set value from config");
SetUsAEnable((bool)PropertiesConfig.EnableUsA);
}
else
{
Debug.Console(1, this, "EnableUsA null, no value specified in config");
}
if (PropertiesConfig.EnableUsB != null)
{
Debug.Console(1, this, "EnableUsB found, attempting to set value from config");
SetUsBEnable((bool)PropertiesConfig.EnableUsB);
}
else
{
Debug.Console(1, this, "EnablePir null, no value specified in config");
}
if (PropertiesConfig.OrWhenVacatedState != null)
{
SetOrWhenVacatedState((bool)PropertiesConfig.OrWhenVacatedState);
}
if (PropertiesConfig.AndWhenVacatedState != null)
{
SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState);
}
}
/// <summary>
/// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class.
/// Then calls the base delegate method to ensure any common event IDs are captured.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
switch (args.EventId)
{
case GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId:
AndWhenVacatedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId:
OrWhenVacatedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.UsAEnabledFeedbackEventId:
UltrasonicAEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.UsBEnabledFeedbackEventId:
UltrasonicBEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId:
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId:
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
break;
}
base.OccSensor_GlsOccupancySensorChange(device, args);
}
/// <summary>
/// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class.
/// Then calls the base delegate method to ensure any common event IDs are captured.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
switch (args.EventId)
{
case GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId:
RawOccupancyPirFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId:
RawOccupancyUsFeedback.FireUpdate();
break;
}
base.OccSensor_BaseEvent(device, args);
}
/// <summary>
/// Sets the OrWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetOrWhenVacatedState(bool state)
{
_occSensor.OrWhenVacated.BoolValue = state;
}
/// <summary>
/// Sets the AndWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetAndWhenVacatedState(bool state)
{
_occSensor.AndWhenVacated.BoolValue = state;
}
/// <summary>
/// Enables or disables the Ultrasonic A sensor
/// </summary>
/// <param name="state"></param>
public void SetUsAEnable(bool state)
{
_occSensor.EnableUsA.BoolValue = state;
_occSensor.DisableUsA.BoolValue = !state;
}
/// <summary>
/// Enables or disables the Ultrasonic B sensor
/// </summary>
/// <param name="state"></param>
public void SetUsBEnable(bool state)
{
_occSensor.EnableUsB.BoolValue = state;
_occSensor.DisableUsB.BoolValue = !state;
}
public void IncrementUsSensitivityInOccupiedState(bool pressRelease)
{
_occSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInOccupiedState(bool pressRelease)
{
_occSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementUsSensitivityInVacantState(bool pressRelease)
{
_occSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInVacantState(bool pressRelease)
{
_occSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
/// <summary>
/// Method to print occ sensor settings to console.
/// </summary>
public override void GetSettings()
{
base.GetSettings();
Debug.Console(0, this, "Ultrasonic Enabled A: {0} | B: {1}",
_occSensor.UsAEnabledFeedback.BoolValue,
_occSensor.UsBEnabledFeedback.BoolValue);
Debug.Console(0, this, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}",
_occSensor.UsSensitivityInOccupiedStateFeedback.UShortValue,
_occSensor.UsSensitivityInVacantStateFeedback.UShortValue);
var dash = new string('*', 50);
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
}
}
public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory<GlsOdtOccupancySensorController>
{
public GlsOdtOccupancySensorControllerFactory()
public new GlsOdtCCn OccSensor { get; private set; }
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
TypeNames = new List<string> { "glsodtccn" };
AddPreActivationAction(() =>
{
OccSensor = preActivationFunc(config);
RegisterCrestronGenericBase(OccSensor);
RegisterGlsOdtSensorBaseController(OccSensor);
AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue);
OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue);
UltrasonicAEnabledFeedback = new BoolFeedback(() => OccSensor.UsAEnabledFeedback.BoolValue);
UltrasonicBEnabledFeedback = new BoolFeedback(() => OccSensor.UsBEnabledFeedback.BoolValue);
RawOccupancyPirFeedback = new BoolFeedback(() => OccSensor.RawOccupancyPirFeedback.BoolValue);
RawOccupancyUsFeedback = new BoolFeedback(() => OccSensor.RawOccupancyUsFeedback.BoolValue);
UltrasonicSensitivityInVacantStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInVacantStateFeedback.UShortValue);
UltrasonicSensitivityInOccupiedStateFeedback = new IntFeedback(() => OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue);
});
}
/// <summary>
/// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class.
/// Then calls the base delegate method to ensure any common event IDs are captured.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
if (args.EventId == GlsOccupancySensorBase.AndWhenVacatedFeedbackEventId)
AndWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.OrWhenVacatedFeedbackEventId)
OrWhenVacatedFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsAEnabledFeedbackEventId)
UltrasonicAEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsBEnabledFeedbackEventId)
UltrasonicBEnabledFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInOccupiedStateFeedbackEventId)
UltrasonicSensitivityInOccupiedStateFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.UsSensitivityInVacantStateFeedbackEventId)
UltrasonicSensitivityInVacantStateFeedback.FireUpdate();
base.OccSensor_GlsOccupancySensorChange(device, args);
}
/// <summary>
/// Overrides the base class event delegate to fire feedbacks for event IDs that pertain to this extended class.
/// Then calls the base delegate method to ensure any common event IDs are captured.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected override void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
if (args.EventId == GlsOccupancySensorBase.RawOccupancyPirFeedbackEventId)
RawOccupancyPirFeedback.FireUpdate();
else if (args.EventId == GlsOccupancySensorBase.RawOccupancyUsFeedbackEventId)
RawOccupancyUsFeedback.FireUpdate();
base.OccSensor_BaseEvent(device, args);
}
/// <summary>
/// Sets the OrWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetOrWhenVacatedState(bool state)
{
OccSensor.OrWhenVacated.BoolValue = state;
}
/// <summary>
/// Sets the AndWhenVacated state
/// </summary>
/// <param name="state"></param>
public void SetAndWhenVacatedState(bool state)
{
OccSensor.AndWhenVacated.BoolValue = state;
}
/// <summary>
/// Enables or disables the Ultrasonic A sensor
/// </summary>
/// <param name="state"></param>
public void SetUsAEnable(bool state)
{
OccSensor.EnableUsA.BoolValue = state;
OccSensor.DisableUsA.BoolValue = !state;
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
/// <summary>
/// Enables or disables the Ultrasonic B sensor
/// </summary>
/// <param name="state"></param>
public void SetUsBEnable(bool state)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc);
OccSensor.EnableUsB.BoolValue = state;
OccSensor.DisableUsB.BoolValue = !state;
}
public void IncrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
#region PreActivation
private static GlsOdtCCn GetGlsOdtCCn(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
var branchId = control.ControlPortNumber;
var parentKey = String.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
@@ -277,6 +194,24 @@ namespace PepperDash.Essentials.Core
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
#endregion
public class GlsOdtOccupancySensorControllerFactory : EssentialsDeviceFactory<GlsOdtOccupancySensorController>
{
public GlsOdtOccupancySensorControllerFactory()
{
TypeNames = new List<string>() { "glsodtccn" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc);
}
}
}

View File

@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.GeneralIO;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
public class GlsOirOccupancySensorController:GlsOccupancySensorBaseController
{
private GlsOirCCn _occSensor;
public GlsOirOccupancySensorController(string key, Func<DeviceConfig, GlsOirCCn> preActivationFunc,DeviceConfig config) : this(key,config.Name, preActivationFunc, config)
{
}
public GlsOirOccupancySensorController(string key, string name, Func<DeviceConfig, GlsOirCCn> preActivationFunc, DeviceConfig config) : base(key, name, config)
{
AddPreActivationAction(() =>
{
_occSensor = preActivationFunc(config);
RegisterCrestronGenericBase(_occSensor);
RegisterGlsOccupancySensorBaseController(_occSensor);
});
}
#region Overrides of CrestronGenericBridgeableBaseDevice
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
}
#endregion
}
public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<GlsOccupancySensorBaseController>
{
public GlsOccupancySensorBaseControllerFactory()
{
TypeNames = new List<string> { "glsoirccn" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOirOccupancySensorController Device");
return new GlsOirOccupancySensorController(dc.Key, GetGlsOirCCn, dc);
}
private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc)
{
var control = CommFactory.GetControlPropertiesConfig(dc);
var cresnetId = control.CresnetIdInt;
var branchId = control.ControlPortNumber;
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
return new GlsOirCCn(cresnetId, Global.ControlSystem);
}
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
if (cresnetBridge != null)
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
return null;
}
}
}

View File

@@ -4,7 +4,7 @@ using Crestron.SimplSharpPro.GeneralIO;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Bridges.JoinMaps;
using PepperDash_Essentials_Core.Bridges.JoinMaps;
using System;
using System.Collections.Generic;

View File

@@ -48,39 +48,39 @@
<ItemGroup>
<Reference Include="Crestron.SimplSharpPro.DeviceSupport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.DM, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.EthernetCommunications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.Fusion, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.Gateways, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.GeneralIO.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.Remotes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.ThreeSeriesCards, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll</HintPath>
</Reference>
<Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
@@ -89,30 +89,30 @@
</Reference>
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SimplSharpNewtonsoft, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll</HintPath>
</Reference>
<Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
</Reference>
<Reference Include="SimplSharpTimerEventInterface, Version=1.0.6197.20052, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpTimerEventInterface.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
@@ -143,7 +143,6 @@
<Compile Include="Bridges\JoinMaps\Hrxxx0WirelessRemoteControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\IBasicCommunicationJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\IDigitalInputJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\IRBlurayBaseJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\SetTopBoxControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
@@ -184,9 +183,6 @@
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
<Compile Include="Crestron IO\StatusSign\StatusSignController.cs" />
<Compile Include="Device Info\DeviceInfo.cs" />
<Compile Include="Device Info\DeviceInfoEventArgs.cs" />
<Compile Include="Device Info\IDeviceInfoProvider.cs" />
<Compile Include="Devices\CodecInterfaces.cs" />
<Compile Include="Devices\CrestronProcessor.cs" />
<Compile Include="Devices\DeviceApiBase.cs" />
@@ -194,17 +190,12 @@
<Compile Include="Devices\EssentialsBridgeableDevice.cs" />
<Compile Include="Devices\EssentialsDevice.cs" />
<Compile Include="Devices\GenericIRController.cs" />
<Compile Include="Devices\IDspPreset.cs" />
<Compile Include="Devices\IProjectorInterfaces.cs" />
<Compile Include="Devices\PC\InRoomPc.cs" />
<Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" />
<Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" />
<Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" />
<Compile Include="DeviceTypeInterfaces\IHasBranding.cs" />
<Compile Include="DeviceTypeInterfaces\ILanguageDefinition.cs" />
<Compile Include="DeviceTypeInterfaces\IHasFarEndContentStatus.cs" />
<Compile Include="DeviceTypeInterfaces\IHasPhoneDialing.cs" />
<Compile Include="DeviceTypeInterfaces\IMobileControl.cs" />
@@ -221,15 +212,10 @@
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="Fusion\FusionEventHandlers.cs" />
<Compile Include="Fusion\FusionProcessorQueries.cs" />
<Compile Include="Fusion\EssentialsHuddleSpaceRoomFusionRoomJoinMap.cs" />
<Compile Include="Fusion\FusionRviDataClasses.cs" />
<Compile Include="Gateways\CenRfgwController.cs" />
<Compile Include="Gateways\EssentialsRfGatewayConfig.cs" />
<Compile Include="Global\EthernetAdapterInfo.cs" />
<Compile Include="Interfaces\ILogStrings.cs" />
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
<Compile Include="Occupancy\GlsOirOccupancySensorController.cs" />
<Compile Include="Queues\ComsMessage.cs" />
<Compile Include="Queues\ProcessStringMessage.cs" />
<Compile Include="Queues\GenericQueue.cs" />
@@ -285,7 +271,6 @@
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
<Compile Include="Room\EssentialsRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
<Compile Include="Room\Interfaces.cs" />
<Compile Include="Room\iOccupancyStatusProvider.cs" />
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
@@ -329,7 +314,6 @@
<Compile Include="Routing\TieLine.cs" />
<Compile Include="Queues\StringResponseProcessor.cs" />
<Compile Include="Timers\CountdownTimer.cs" />
<Compile Include="Timers\RetriggerableTimer.cs" />
<Compile Include="Touchpanels\CrestronTouchpanelPropertiesConfig.cs" />
<Compile Include="Touchpanels\Interfaces.cs" />
<Compile Include="Touchpanels\Keyboards\HabaneroKeyboardController.cs" />
@@ -340,7 +324,6 @@
<Compile Include="UI PageManagers\SinglePageManager.cs" />
<Compile Include="UI PageManagers\PageManager.cs" />
<Compile Include="UI PageManagers\SetTopBoxTwoPanelPageManager.cs" />
<Compile Include="Utilities\ActionSequence.cs" />
<Compile Include="VideoStatus\VideoStatusOutputs.cs" />
<Compile Include="Crestron\CrestronGenericBaseDevice.cs" />
<Compile Include="DeviceControlsParentInterfaces\IPresentationSource.cs" />

View File

@@ -14,7 +14,7 @@
<tags>crestron 3series 4series</tags>
<repository type="git" url="https://github.com/PepperDash/Essentials"/>
<dependencies>
<dependency id="PepperDashCore" version="[1.0.45, 1.1.0)"/>
<dependency id="PepperDashCore" version="[1.0, 1.1)"/>
</dependencies>
</metadata>
<files>

View File

@@ -402,16 +402,13 @@ namespace PepperDash.Essentials
/// Loads a
/// </summary>
/// <param name="plugin"></param>
/// <param name="loadedAssembly"></param>
static void LoadCustomPlugin(IPluginDeviceFactory plugin, LoadedAssembly loadedAssembly)
{
var passed = Global.IsRunningMinimumVersionOrHigher(plugin.MinimumEssentialsFrameworkVersion);
if (!passed)
{
Debug.Console(0, Debug.ErrorLogLevel.Error,
"\r\n********************\r\n\tPlugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin {1}\r\n********************",
plugin.MinimumEssentialsFrameworkVersion, loadedAssembly.Name);
Debug.Console(0, Debug.ErrorLogLevel.Error, "Plugin indicates minimum Essentials version {0}. Dependency check failed. Skipping Plugin", plugin.MinimumEssentialsFrameworkVersion);
return;
}
else

View File

@@ -1,300 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
//using SSMono.IO;
using PepperDash.Core.WebApi.Presets;
namespace PepperDash.Essentials.Core.Presets
{
/// <summary>
/// Class that represents the model behind presets display
/// </summary>
public class DevicePresetsModel : Device
{
public delegate void PresetRecalledCallback(ISetTopBoxNumericKeypad device, string channel);
/// <summary>
/// Class that represents the model behind presets display
/// </summary>
public class DevicePresetsModel : Device
{
public event EventHandler PresetsLoaded;
public delegate void PresetsSavedCallback(List<PresetChannel> presets);
public int PulseTime { get; set; }
public int DigitSpacingMS { get; set; }
public bool PresetsAreLoaded { get; private set; }
private readonly CCriticalSection _fileOps = new CCriticalSection();
private readonly bool _initSuccess;
public List<PresetChannel> PresetsList { get { return _PresetsList.ToList(); } }
List<PresetChannel> _PresetsList;
public int Count { get { return PresetsList != null ? PresetsList.Count : 0; } }
private readonly ISetTopBoxNumericKeypad _setTopBox;
public bool UseLocalImageStorage { get; set; }
public string ImagesLocalHostPrefix { get; set; }
public string ImagesPathPrefix { get; set; }
public string ListPathPrefix { get; set; }
/// <summary>
/// The methods on the STB device to call when dialing
/// </summary>
private Dictionary<char, Action<bool>> _dialFunctions;
/// <summary>
/// The methods on the STB device to call when dialing
/// </summary>
Dictionary<char, Action<bool>> DialFunctions;
Action<bool> EnterFunction;
private bool _dialIsRunning;
private Action<bool> _enterFunction;
private string _filePath;
bool DialIsRunning;
string FilePath;
bool InitSuccess;
//SSMono.IO.FileSystemWatcher ListWatcher;
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
: this(key, fileName)
{
try
{
_setTopBox = setTopBox;
public DevicePresetsModel(string key, ISetTopBoxNumericKeypad setTopBox, string fileName)
: base(key)
{
PulseTime = 150;
DigitSpacingMS = 150;
// Grab the digit functions from the device
// If any fail, the whole thing fails peacefully
_dialFunctions = new Dictionary<char, Action<bool>>(10)
{
{'1', setTopBox.Digit1},
{'2', setTopBox.Digit2},
{'3', setTopBox.Digit3},
{'4', setTopBox.Digit4},
{'5', setTopBox.Digit5},
{'6', setTopBox.Digit6},
{'7', setTopBox.Digit7},
{'8', setTopBox.Digit8},
{'9', setTopBox.Digit9},
{'0', setTopBox.Digit0},
{'-', setTopBox.Dash}
};
}
catch
{
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
_dialFunctions = null;
return;
}
try
{
// Grab the digit functions from the device
// If any fail, the whole thing fails peacefully
DialFunctions = new Dictionary<char, Action<bool>>(10)
{
{ '1', setTopBox.Digit1 },
{ '2', setTopBox.Digit2 },
{ '3', setTopBox.Digit3 },
{ '4', setTopBox.Digit4 },
{ '5', setTopBox.Digit5 },
{ '6', setTopBox.Digit6 },
{ '7', setTopBox.Digit7 },
{ '8', setTopBox.Digit8 },
{ '9', setTopBox.Digit9 },
{ '0', setTopBox.Digit0 },
{ '-', setTopBox.Dash }
};
}
catch
{
Debug.Console(0, "DevicePresets '{0}', not attached to INumericKeypad device. Ignoring", key);
DialFunctions = null;
return;
}
_enterFunction = setTopBox.KeypadEnter;
}
EnterFunction = setTopBox.KeypadEnter;
public DevicePresetsModel(string key, string fileName) : base(key)
{
PulseTime = 150;
DigitSpacingMs = 150;
UseLocalImageStorage = true;
UseLocalImageStorage = true;
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS,0);
ImagesPathPrefix = @"/presets/images.zip/";
ListPathPrefix = @"/html/presets/lists/";
ImagesLocalHostPrefix = "http://" + CrestronEthernetHelper.GetEthernetParameter(
CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
ImagesPathPrefix = @"/presets/images.zip/";
ListPathPrefix = @"/html/presets/lists/";
SetFileName(fileName);
SetFileName(fileName);
_initSuccess = true;
}
public event PresetRecalledCallback PresetRecalled;
public event PresetsSavedCallback PresetsSaved;
public int PulseTime { get; set; }
public int DigitSpacingMs { get; set; }
public bool PresetsAreLoaded { get; private set; }
public List<PresetChannel> PresetsList { get; private set; }
public int Count
{
get { return PresetsList != null ? PresetsList.Count : 0; }
}
public bool UseLocalImageStorage { get; set; }
public string ImagesLocalHostPrefix { get; set; }
public string ImagesPathPrefix { get; set; }
public string ListPathPrefix { get; set; }
public event EventHandler PresetsLoaded;
//ListWatcher = new FileSystemWatcher(@"\HTML\presets\lists");
//ListWatcher.NotifyFilter = NotifyFilters.LastWrite;
//ListWatcher.EnableRaisingEvents = true;
//ListWatcher.Changed += ListWatcher_Changed;
InitSuccess = true;
}
public void SetFileName(string path)
{
_filePath = ListPathPrefix + path;
public void SetFileName(string path)
{
FilePath = ListPathPrefix + path;
LoadChannels();
}
Debug.Console(2, this, "Setting presets file path to {0}", _filePath);
LoadChannels();
}
public void LoadChannels()
{
PresetsAreLoaded = false;
try
{
var pl = JsonConvert.DeserializeObject<PresetsList>(Crestron.SimplSharp.CrestronIO.File.ReadToEnd(FilePath, Encoding.ASCII));
Name = pl.Name;
_PresetsList = pl.Channels;
}
catch (Exception e)
{
Debug.Console(2, this, "LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}", FilePath, e.Message);
// Just save a default empty list
_PresetsList = new List<PresetChannel>();
}
PresetsAreLoaded = true;
public void LoadChannels()
{
try
{
_fileOps.Enter();
var handler = PresetsLoaded;
if (handler != null)
handler(this, EventArgs.Empty);
}
Debug.Console(2, this, "Loading presets from {0}", _filePath);
PresetsAreLoaded = false;
try
{
var pl = JsonConvert.DeserializeObject<PresetsList>(File.ReadToEnd(_filePath, Encoding.ASCII));
Name = pl.Name;
PresetsList = pl.Channels;
}
catch (Exception e)
{
Debug.Console(2, this,
"LoadChannels: Error reading presets file. These presets will be empty:\r '{0}'\r Error:{1}",
_filePath, e.Message);
// Just save a default empty list
PresetsList = new List<PresetChannel>();
}
PresetsAreLoaded = true;
public void Dial(int presetNum)
{
if (presetNum <= _PresetsList.Count)
Dial(_PresetsList[presetNum - 1].Channel);
}
var handler = PresetsLoaded;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
finally
{
_fileOps.Leave();
}
}
public void Dial(string chanNum)
{
if (DialIsRunning || !InitSuccess) return;
if (DialFunctions == null)
{
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
return;
}
public void Dial(int presetNum)
{
if (presetNum <= PresetsList.Count)
{
Dial(PresetsList[presetNum - 1].Channel);
}
}
DialIsRunning = true;
CrestronInvoke.BeginInvoke(o =>
{
foreach (var c in chanNum.ToCharArray())
{
if (DialFunctions.ContainsKey(c))
Pulse(DialFunctions[c]);
CrestronEnvironment.Sleep(DigitSpacingMS);
}
public void Dial(string chanNum)
{
if (_dialIsRunning || !_initSuccess)
{
return;
}
if (_dialFunctions == null)
{
Debug.Console(1, "DevicePresets '{0}', not attached to keypad device. Ignoring channel", Key);
return;
}
if (EnterFunction != null)
Pulse(EnterFunction);
DialIsRunning = false;
});
}
_dialIsRunning = true;
CrestronInvoke.BeginInvoke(o =>
{
foreach (var c in chanNum.ToCharArray())
{
if (_dialFunctions.ContainsKey(c))
{
Pulse(_dialFunctions[c]);
}
CrestronEnvironment.Sleep(DigitSpacingMs);
}
void Pulse(Action<bool> act)
{
act(true);
CrestronEnvironment.Sleep(PulseTime);
act(false);
}
if (_enterFunction != null)
{
Pulse(_enterFunction);
}
_dialIsRunning = false;
});
if (_setTopBox == null) return;
OnPresetRecalled(_setTopBox, chanNum);
}
public void Dial(int presetNum, ISetTopBoxNumericKeypad setTopBox)
{
if (presetNum <= PresetsList.Count)
{
Dial(PresetsList[presetNum - 1].Channel, setTopBox);
}
}
public void Dial(string chanNum, ISetTopBoxNumericKeypad setTopBox)
{
_dialFunctions = new Dictionary<char, Action<bool>>(10)
{
{'1', setTopBox.Digit1},
{'2', setTopBox.Digit2},
{'3', setTopBox.Digit3},
{'4', setTopBox.Digit4},
{'5', setTopBox.Digit5},
{'6', setTopBox.Digit6},
{'7', setTopBox.Digit7},
{'8', setTopBox.Digit8},
{'9', setTopBox.Digit9},
{'0', setTopBox.Digit0},
{'-', setTopBox.Dash}
};
_enterFunction = setTopBox.KeypadEnter;
OnPresetRecalled(setTopBox, chanNum);
Dial(chanNum);
}
private void OnPresetRecalled(ISetTopBoxNumericKeypad setTopBox, string channel)
{
var handler = PresetRecalled;
if (handler == null)
{
return;
}
handler(setTopBox, channel);
}
public void UpdatePreset(int index, PresetChannel preset)
{
if (index >= PresetsList.Count)
{
return;
}
PresetsList[index] = preset;
SavePresets();
OnPresetsSaved();
}
public void UpdatePresets(List<PresetChannel> presets)
{
PresetsList = presets;
SavePresets();
OnPresetsSaved();
}
private void SavePresets()
{
try
{
_fileOps.Enter();
var pl = new PresetsList {Channels = PresetsList, Name = Name};
var json = JsonConvert.SerializeObject(pl, Formatting.Indented);
using (var file = File.Open(_filePath, FileMode.Truncate))
{
file.Write(json, Encoding.UTF8);
}
}
finally
{
_fileOps.Leave();
}
}
private void OnPresetsSaved()
{
var handler = PresetsSaved;
if (handler == null) return;
handler(PresetsList);
}
private void Pulse(Action<bool> act)
{
act(true);
CrestronEnvironment.Sleep(PulseTime);
act(false);
}
}
/// <summary>
/// Event handler for filesystem watcher. When directory changes, this is called
/// </summary>
//void ListWatcher_Changed(object sender, FileSystemEventArgs e)
//{
// Debug.Console(1, this, "folder modified: {0}", e.FullPath);
// if (e.FullPath.Equals(FilePath, StringComparison.OrdinalIgnoreCase))
// {
// Debug.Console(1, this, "File changed: {0}", e.ChangeType);
// LoadChannels();
// }
//}
}
}

View File

@@ -10,22 +10,19 @@ namespace PepperDash.Essentials.Core.Presets
public class PresetChannel
{
[JsonProperty(Required = Required.Always,PropertyName = "name")]
[JsonProperty(Required = Required.Always)]
public string Name { get; set; }
[JsonProperty(Required = Required.Always, PropertyName = "iconUrl")]
[JsonProperty(Required = Required.Always)]
public string IconUrl { get; set; }
[JsonProperty(Required = Required.Always, PropertyName = "channel")]
[JsonProperty(Required = Required.Always)]
public string Channel { get; set; }
}
public class PresetsList
{
[JsonProperty(Required=Required.Always,PropertyName = "name")]
[JsonProperty(Required=Required.Always)]
public string Name { get; set; }
[JsonProperty(Required = Required.Always, PropertyName = "channels")]
[JsonProperty(Required = Required.Always)]
public List<PresetChannel> Channels { get; set; }
}
}

View File

@@ -1,83 +1,11 @@
using System;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Queues
{
/// <summary>
/// IBasicCommunication Message for IQueue
/// </summary>
public class ComsMessage : IQueueMessage
{
private readonly byte[] _bytes;
private readonly IBasicCommunication _coms;
private readonly string _string;
private readonly bool _isByteMessage;
/// <summary>
/// Constructor for a string message
/// </summary>
/// <param name="coms">IBasicCommunication to send the message</param>
/// <param name="message">Message to send</param>
public ComsMessage(IBasicCommunication coms, string message)
{
Validate(coms, message);
_coms = coms;
_string = message;
}
/// <summary>
/// Constructor for a byte message
/// </summary>
/// <param name="coms">IBasicCommunication to send the message</param>
/// <param name="message">Message to send</param>
public ComsMessage(IBasicCommunication coms, byte[] message)
{
Validate(coms, message);
_coms = coms;
_bytes = message;
_isByteMessage = true;
}
private void Validate(IBasicCommunication coms, object message)
{
if (coms == null)
throw new ArgumentNullException("coms");
if (message == null)
throw new ArgumentNullException("message");
}
/// <summary>
/// Dispatchs the string/byte[] to the IBasicCommunication specified
/// </summary>
public void Dispatch()
{
if (_isByteMessage)
{
_coms.SendBytes(_bytes);
}
else
{
_coms.SendText(_string);
}
}
/// <summary>
/// Shows either the byte[] or string to be sent
/// </summary>
public override string ToString()
{
return _bytes != null ? _bytes.ToString() : _string;
}
}
}
namespace PepperDash_Essentials_Core.Queues
{
/// <summary>
/// IBasicCommunication Message for IQueue
/// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class ComsMessage : IQueueMessage
{
private readonly byte[] _bytes;
@@ -112,7 +40,7 @@ namespace PepperDash_Essentials_Core.Queues
private void Validate(IBasicCommunication coms, object message)
{
if (coms == null)
if (_coms == null)
throw new ArgumentNullException("coms");
if (message == null)

View File

@@ -3,274 +3,20 @@ using Crestron.SimplSharp;
using Crestron.SimplSharpPro.CrestronThread;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Queues
{
/// <summary>
/// Threadsafe processing of queued items with pacing if required
/// </summary>
public class GenericQueue : IQueue<IQueueMessage>
{
private readonly string _key;
protected readonly CrestronQueue<IQueueMessage> _queue;
protected readonly Thread _worker;
protected readonly CEvent _waitHandle = new CEvent();
private bool _delayEnabled;
private int _delayTime;
private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority;
/// <summary>
/// If the instance has been disposed.
/// </summary>
public bool Disposed { get; private set; }
/// <summary>
/// Returns the capacity of the CrestronQueue (fixed Size property)
/// </summary>
public int QueueCapacity
{
get
{
return _queue.Size;
}
}
/// <summary>
/// Returns the number of elements currently in the CrestronQueue
/// </summary>
public int QueueCount
{
get
{
return _queue.Count;
}
}
/// <summary>
/// Constructor with no thread priority
/// </summary>
/// <param name="key"></param>
public GenericQueue(string key)
: this(key, _defaultPriority, 0, 0)
{
}
/// <summary>
/// Constructor with queue size
/// </summary>
/// <param name="key"></param>
/// <param name="capacity">Fixed size for the queue to hold</param>
public GenericQueue(string key, int capacity)
: this(key, _defaultPriority, capacity, 0)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="pacing">Pacing in ms between actions</param>
public GenericQueue(int pacing, string key)
: this(key, _defaultPriority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, int capacity)
: this(key, _defaultPriority, capacity, pacing)
{
}
/// <summary>
/// Constructor with pacing and priority
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
: this(key, priority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, 0)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, pacing)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
/// <param name="pacing"></param>
protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing)
{
_key = key;
int cap = 25; // sets default
if (capacity > 0)
{
cap = capacity; // overrides default
}
_queue = new CrestronQueue<IQueueMessage>(cap);
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
{
Priority = priority
};
SetDelayValues(pacing);
}
private void SetDelayValues(int pacing)
{
_delayEnabled = pacing > 0;
_delayTime = pacing;
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
if (programEvent != eProgramStatusEventType.Stopping)
return;
Dispose();
};
}
/// <summary>
/// Thread callback
/// </summary>
/// <param name="obj">The action used to process dequeued items</param>
/// <returns>Null when the thread is exited</returns>
private object ProcessQueue(object obj)
{
while (true)
{
IQueueMessage item = null;
if (_queue.Count > 0)
{
item = _queue.Dequeue();
if (item == null)
break;
}
if (item != null)
{
try
{
Debug.Console(2, this, "Processing queue item: '{0}'", item.ToString());
item.Dispatch();
if (_delayEnabled)
Thread.Sleep(_delayTime);
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
}
}
else _waitHandle.Wait();
}
return null;
}
public void Enqueue(IQueueMessage item)
{
if (Disposed)
{
Debug.Console(1, this, "I've been disposed so you can't enqueue any messages. Are you trying to dispatch a message while the program is stopping?");
return;
}
_queue.Enqueue(item);
_waitHandle.Set();
}
/// <summary>
/// Disposes the thread and cleans up resources. Thread cannot be restarted once
/// disposed.
/// </summary>
public void Dispose()
{
Dispose(true);
CrestronEnvironment.GC.SuppressFinalize(this);
}
/// <summary>
/// Actually does the disposing. If you override this method, be sure to either call the base implementation
/// or clean up all the resources yourself.
/// </summary>
/// <param name="disposing">set to true unless called from finalizer</param>
protected void Dispose(bool disposing)
{
if (Disposed)
return;
if (disposing)
{
Enqueue(null);
_worker.Join();
_waitHandle.Close();
}
Disposed = true;
}
~GenericQueue()
{
Dispose(false);
}
/// <summary>
/// Key
/// </summary>
public string Key
{
get { return _key; }
}
}
}
namespace PepperDash_Essentials_Core.Queues
{
/// <summary>
/// Threadsafe processing of queued items with pacing if required
/// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class GenericQueue : IQueue<IQueueMessage>
{
private readonly string _key;
protected readonly CrestronQueue<IQueueMessage> _queue;
protected readonly Thread _worker;
protected readonly CEvent _waitHandle = new CEvent();
private bool _delayEnabled;
private int _delayTime;
private const Thread.eThreadPriority _defaultPriority = Thread.eThreadPriority.MediumPriority;
private readonly bool _delayEnabled;
private readonly int _delayTime;
/// <summary>
/// If the instance has been disposed.
@@ -278,129 +24,14 @@ namespace PepperDash_Essentials_Core.Queues
public bool Disposed { get; private set; }
/// <summary>
/// Returns the capacity of the CrestronQueue (fixed Size property)
/// Constructor for generic queue with no pacing
/// </summary>
public int QueueCapacity
{
get
{
return _queue.Size;
}
}
/// <summary>
/// Returns the number of elements currently in the CrestronQueue
/// </summary>
public int QueueCount
{
get
{
return _queue.Count;
}
}
/// <summary>
/// Constructor with no thread priority
/// </summary>
/// <param name="key"></param>
/// <param name="key">Key</param>
public GenericQueue(string key)
: this(key, _defaultPriority, 0, 0)
{
}
/// <summary>
/// Constructor with queue size
/// </summary>
/// <param name="key"></param>
/// <param name="capacity">Fixed size for the queue to hold</param>
public GenericQueue(string key, int capacity)
: this(key, _defaultPriority, capacity, 0)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="pacing">Pacing in ms between actions</param>
public GenericQueue(int pacing, string key)
: this(key, _defaultPriority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, int capacity)
: this(key, _defaultPriority, capacity, pacing)
{
}
/// <summary>
/// Constructor with pacing and priority
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
: this(key, priority, 0, pacing)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, 0)
{
}
/// <summary>
/// Constructor with pacing, priority and capacity
/// </summary>
/// <param name="key"></param>
/// <param name="pacing"></param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority, int capacity)
: this(key, priority, capacity, pacing)
{
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="priority"></param>
/// <param name="capacity"></param>
/// <param name="pacing"></param>
protected GenericQueue(string key, Thread.eThreadPriority priority, int capacity, int pacing)
{
_key = key;
int cap = 25; // sets default
if (capacity > 0)
{
cap = capacity; // overrides default
}
_queue = new CrestronQueue<IQueueMessage>(cap);
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
{
Priority = priority
};
SetDelayValues(pacing);
}
private void SetDelayValues(int pacing)
{
_delayEnabled = pacing > 0;
_delayTime = pacing;
_queue = new CrestronQueue<IQueueMessage>();
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running);
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
@@ -411,6 +42,18 @@ namespace PepperDash_Essentials_Core.Queues
};
}
/// <summary>
/// Constructor for generic queue with no pacing
/// </summary>
/// <param name="key">Key</param>
/// <param name="pacing">Pacing in ms between actions</param>
public GenericQueue(string key, int pacing)
: this(key)
{
_delayEnabled = pacing > 0;
_delayTime = pacing;
}
/// <summary>
/// Thread callback
/// </summary>
@@ -440,7 +83,7 @@ namespace PepperDash_Essentials_Core.Queues
}
catch (Exception ex)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
Debug.ConsoleWithLog(0, this, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
}
}
else _waitHandle.Wait();

View File

@@ -5,21 +5,11 @@ using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Queues
namespace PepperDash_Essentials_Core.Queues
{
public interface IQueue<T> : IKeyed, IDisposable where T : class
{
void Enqueue(T item);
bool Disposed { get; }
}
}
namespace PepperDash_Essentials_Core.Queues
{
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public interface IQueue<T> : IKeyed, IDisposable where T : class
{
void Enqueue(T item);
bool Disposed { get; }
}
}

View File

@@ -1,18 +1,7 @@
using System;
namespace PepperDash.Essentials.Core.Queues
namespace PepperDash_Essentials_Core.Queues
{
public interface IQueueMessage
{
void Dispatch();
}
}
namespace PepperDash_Essentials_Core.Queues
{
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public interface IQueueMessage
{
void Dispatch();
}
}

View File

@@ -1,54 +1,10 @@
using System;
namespace PepperDash.Essentials.Core.Queues
{
/// <summary>
/// Message class for processing strings via an IQueue
/// </summary>
public class ProcessStringMessage : IQueueMessage
{
private readonly Action<string> _action;
private readonly string _message;
/// <summary>
/// Constructor
/// </summary>
/// <param name="message">Message to be processed</param>
/// <param name="action">Action to invoke on the message</param>
public ProcessStringMessage(string message, Action<string> action)
{
_message = message;
_action = action;
}
/// <summary>
/// Processes the string with the given action
/// </summary>
public void Dispatch()
{
if (_action == null || String.IsNullOrEmpty(_message))
return;
_action(_message);
}
/// <summary>
/// To string
/// </summary>
/// <returns>The current message</returns>
public override string ToString()
{
return _message ?? String.Empty;
}
}
}
namespace PepperDash_Essentials_Core.Queues
{
/// <summary>
/// Message class for processing strings via an IQueue
/// </summary>
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public class ProcessStringMessage : IQueueMessage
{
private readonly Action<string> _action;

View File

@@ -2,7 +2,7 @@
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Queues
namespace PepperDash_Essentials_Core.Queues
{
public sealed class StringResponseProcessor : IKeyed, IDisposable
{
@@ -98,110 +98,6 @@ namespace PepperDash.Essentials.Core.Queues
/// </summary>
public bool Disposed { get; private set; }
~StringResponseProcessor()
{
Dispose(false);
}
}
}
namespace PepperDash_Essentials_Core.Queues
{
[Obsolete("Use PepperDash.Essentials.Core.Queues")]
public sealed class StringResponseProcessor : IKeyed, IDisposable
{
private readonly Action<string> _processStringAction;
private readonly IQueue<IQueueMessage> _queue;
private readonly IBasicCommunication _coms;
private readonly CommunicationGather _gather;
private StringResponseProcessor(string key, Action<string> processStringAction)
{
_processStringAction = processStringAction;
_queue = new GenericQueue(key);
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
if (programEvent != eProgramStatusEventType.Stopping)
return;
Dispose();
};
}
/// <summary>
/// Constructor that builds an instance and subscribes to coms TextReceived for processing
/// </summary>
/// <param name="coms">Com port to process strings from</param>
/// <param name="processStringAction">Action to process the incoming strings</param>
public StringResponseProcessor(IBasicCommunication coms, Action<string> processStringAction)
: this(coms.Key, processStringAction)
{
_coms = coms;
coms.TextReceived += OnResponseReceived;
}
/// <summary>
/// Constructor that builds an instance and subscribes to gather Line Received for processing
/// </summary>
/// <param name="gather">Gather to process strings from</param>
/// <param name="processStringAction">Action to process the incoming strings</param>
public StringResponseProcessor(CommunicationGather gather, Action<string> processStringAction)
: this(gather.Port.Key, processStringAction)
{
_gather = gather;
gather.LineReceived += OnResponseReceived;
}
private void OnResponseReceived(object sender, GenericCommMethodReceiveTextArgs args)
{
_queue.Enqueue(new ProcessStringMessage(args.Text, _processStringAction));
}
/// <summary>
/// Key
/// </summary>
public string Key
{
get { return _queue.Key; }
}
/// <summary>
/// Disposes the instance and cleans up resources.
/// </summary>
public void Dispose()
{
Dispose(true);
CrestronEnvironment.GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (Disposed)
return;
if (disposing)
{
if (_coms != null)
_coms.TextReceived -= OnResponseReceived;
if (_gather != null)
{
_gather.LineReceived -= OnResponseReceived;
_gather.Stop();
}
_queue.Dispose();
}
Disposed = true;
}
/// <summary>
/// If the instance has been disposed or not. If it has, you can not use it anymore
/// </summary>
public bool Disposed { get; private set; }
~StringResponseProcessor()
{
Dispose(false);

View File

@@ -83,7 +83,7 @@ namespace PepperDash.Essentials.Core
}
}
void _gateway_IsReadyEvent(object sender, IsReadyEventArgs e)
void _gateway_IsReadyEvent(object sender, PepperDash_Essentials_Core.IsReadyEventArgs e)
{
if (e.IsReady != true) return;
_remote = GetHr1x0WirelessRemote(_config);

View File

@@ -169,15 +169,10 @@ namespace PepperDash.Essentials.Core
void FeatureEventGroup_UserGroupCallBack(ScheduledEvent SchEvent, ScheduledEventCommon.eCallbackReason type)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "{0}:{1} @ {2}", SchEvent.Name, type, DateTime.Now);
if (type == ScheduledEventCommon.eCallbackReason.NormalExpiration)
{
SchEvent.Acknowledge();
if (SchEvent.Name == FeatureEnableEventName)
{
if (PropertiesConfig.EnableRoomOnWhenOccupied)
FeatureEnabled = true;
@@ -253,8 +248,9 @@ namespace PepperDash.Essentials.Core
schEvent = new ScheduledEvent(name, FeatureEventGroup);
// Set up its initial properties
schEvent.Acknowledgeable = false;
if(!schEvent.Acknowledgeable)
schEvent.Acknowledgeable = true;
if(!schEvent.Persistent)
schEvent.Persistent = true;
@@ -291,7 +287,7 @@ namespace PepperDash.Essentials.Core
Debug.Console(1, this, "Event '{0}' Absolute time set to {1}", schEvent.Name, schEvent.DateAndTime.ToString());
//CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
CalculateAndSetAcknowledgeExpirationTimeout(schEvent, FeatureEnabledTime, FeatureDisabledTime);
schEvent.Recurrence.Weekly(eventRecurrennce);

View File

@@ -1,41 +0,0 @@
using System.Collections.Generic;
using Crestron.SimplSharp.Scheduler;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Room.Config
{
public class EssentialsRoomScheduledEventsConfig
{
[JsonProperty("scheduledEvents")]
public List<ScheduledEventConfig> ScheduledEvents;
}
public class ScheduledEventConfig
{
[JsonProperty("key")]
public string Key;
[JsonProperty("name")]
public string Name;
[JsonProperty("days")]
public ScheduledEventCommon.eWeekDays Days;
[JsonProperty("time")]
public string Time;
[JsonProperty("actions")]
public List<DeviceActionWrapper> Actions;
[JsonProperty("persistent")]
public bool Persistent;
[JsonProperty("acknowledgeable")]
public bool Acknowledgeable;
[JsonProperty("enable")]
public bool Enable;
}
}

View File

@@ -1,388 +1,368 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Scheduler;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public abstract class EssentialsRoomBase : ReconfigurableDevice
{
/// <summary>
///
/// </summary>
public BoolFeedback OnFeedback { get; private set; }
/// <summary>
/// Fires when the RoomOccupancy object is set
/// </summary>
public event EventHandler<EventArgs> RoomOccupancyIsSet;
public BoolFeedback IsWarmingUpFeedback { get; private set; }
public BoolFeedback IsCoolingDownFeedback { get; private set; }
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
public bool OccupancyStatusProviderIsRemote { get; private set; }
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
/// <summary>
/// Indicates if this room is Mobile Control Enabled
/// </summary>
public bool IsMobileControlEnabled { get; private set; }
/// <summary>
/// The bridge for this room if Mobile Control is enabled
/// </summary>
public IMobileControlRoomBridge MobileControlRoomBridge { get; private set; }
/// <summary>
/// The config name of the source list
/// </summary>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Scheduler;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Core
{
/// <summary>
///
/// </summary>
public abstract class EssentialsRoomBase : ReconfigurableDevice
{
/// <summary>
///
/// </summary>
public BoolFeedback OnFeedback { get; private set; }
/// <summary>
/// Fires when the RoomOccupancy object is set
/// </summary>
public event EventHandler<EventArgs> RoomOccupancyIsSet;
public BoolFeedback IsWarmingUpFeedback { get; private set; }
public BoolFeedback IsCoolingDownFeedback { get; private set; }
public IOccupancyStatusProvider RoomOccupancy { get; private set; }
public bool OccupancyStatusProviderIsRemote { get; private set; }
protected abstract Func<bool> IsWarmingFeedbackFunc { get; }
protected abstract Func<bool> IsCoolingFeedbackFunc { get; }
/// <summary>
/// Indicates if this room is Mobile Control Enabled
/// </summary>
public bool IsMobileControlEnabled { get; private set; }
/// <summary>
/// The bridge for this room if Mobile Control is enabled
/// </summary>
public IMobileControlRoomBridge MobileControlRoomBridge { get; private set; }
/// <summary>
/// The config name of the source list
/// </summary>
///
protected string _SourceListKey;
public string SourceListKey {
protected string _SourceListKey;
public virtual string SourceListKey {
get
{
return _SourceListKey;
}
private set
set
{
if (value != _SourceListKey)
{
_SourceListKey = value;
}
_SourceListKey = value;
}
}
protected const string _defaultSourceListKey = "default";
/// <summary>
/// Timer used for informing the UIs of a shutdown
/// </summary>
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
/// <summary>
///
/// </summary>
public int ShutdownPromptSeconds { get; set; }
public int ShutdownVacancySeconds { get; set; }
public eShutdownType ShutdownType { get; private set; }
public EssentialsRoomEmergencyBase Emergency { get; set; }
public Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; }
public string LogoUrlLightBkgnd { get; set; }
public string LogoUrlDarkBkgnd { get; set; }
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
public eVacancyMode VacancyMode { get; private set; }
/// <summary>
/// Seconds after vacancy prompt is displayed until shutdown
/// </summary>
protected int RoomVacancyShutdownSeconds;
/// <summary>
/// Seconds after vacancy detected until prompt is displayed
/// </summary>
protected int RoomVacancyShutdownPromptSeconds;
/// <summary>
///
/// </summary>
protected abstract Func<bool> OnFeedbackFunc { get; }
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
/// <summary>
/// When volume control devices change, should we zero the one that we are leaving?
/// </summary>
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
public EssentialsRoomBase(DeviceConfig config)
: base(config)
{
// Setup the ShutdownPromptTimer
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
{
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
ShutdownType = eShutdownType.None;
};
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
ShutdownPromptSeconds = 60;
ShutdownVacancySeconds = 120;
ShutdownType = eShutdownType.None;
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
//{
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
// ShutdownType = ShutdownType.Vacancy;
//};
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
VacancyMode = eVacancyMode.None;
OnFeedback = new BoolFeedback(OnFeedbackFunc);
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
AddPostActivationAction(() =>
{
if (RoomOccupancy != null)
OnRoomOccupancyIsSet();
});
}
public override bool CustomActivate()
{
SetUpMobileControl();
return base.CustomActivate();
}
/// <summary>
/// Sets the SourceListKey property to the passed in value or the default if no value passed in
/// </summary>
/// <param name="sourceListKey"></param>
protected void SetSourceListKey(string sourceListKey)
{
if (!string.IsNullOrEmpty(sourceListKey))
{
SourceListKey = sourceListKey;
}
else
{
sourceListKey = _defaultSourceListKey;
}
}
/// <summary>
/// If mobile control is enabled, sets the appropriate properties
/// </summary>
void SetUpMobileControl()
{
var mcBridgeKey = string.Format("mobileControlBridge-{0}", Key);
var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey);
if (mcBridge == null)
{
Debug.Console(1, this, "*********************Mobile Control Bridge Not found for this room.");
IsMobileControlEnabled = false;
return;
}
else
{
MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge;
Debug.Console(1, this, "*********************Mobile Control Bridge found and enabled for this room");
IsMobileControlEnabled = true;
}
}
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
{
switch (VacancyMode)
{
case eVacancyMode.None:
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
break;
case eVacancyMode.InInitialVacancy:
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
break;
case eVacancyMode.InShutdownWarning:
{
StartShutdown(eShutdownType.Vacancy);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
break;
}
default:
break;
}
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
public void StartShutdown(eShutdownType type)
{
// Check for shutdowns running. Manual should override other shutdowns
if (type == eShutdownType.Manual)
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
else if (type == eShutdownType.Vacancy)
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
ShutdownType = type;
ShutdownPromptTimer.Start();
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
}
public void StartRoomVacancyTimer(eVacancyMode mode)
{
if (mode == eVacancyMode.None)
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
else if (mode == eVacancyMode.InInitialVacancy)
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
else if (mode == eVacancyMode.InShutdownWarning)
RoomVacancyShutdownTimer.SecondsToCount = 60;
VacancyMode = mode;
RoomVacancyShutdownTimer.Start();
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
}
/// <summary>
/// Resets the vacancy mode and shutsdwon the room
/// </summary>
public void Shutdown()
{
VacancyMode = eVacancyMode.None;
EndShutdown();
}
/// <summary>
/// This method is for the derived class to define it's specific shutdown
/// requirements but should not be called directly. It is called by Shutdown()
/// </summary>
protected abstract void EndShutdown();
/// <summary>
/// Override this to implement a default volume level(s) method
/// </summary>
public abstract void SetDefaultLevels();
/// <summary>
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
/// </summary>
/// <param name="statusProvider"></param>
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
{
if (statusProvider == null)
{
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
return;
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", (statusProvider as Device).Key);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
// If status provider is fusion, set flag to remote
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
OccupancyStatusProviderIsRemote = true;
if(timeoutMinutes > 0)
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
RoomOccupancy = statusProvider;
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
OnRoomOccupancyIsSet();
}
void OnRoomOccupancyIsSet()
{
var handler = RoomOccupancyIsSet;
if (handler != null)
handler(this, new EventArgs());
}
/// <summary>
/// To allow base class to power room on to last source
/// </summary>
public abstract void PowerOnToDefaultOrLastSource();
/// <summary>
/// To allow base class to power room on to default source
/// </summary>
/// <returns></returns>
public abstract bool RunDefaultPresentRoute();
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
{
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
// Trigger the timer when the room is vacant
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
}
else
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Occupancy Detected");
// Reset the timer when the room is occupied
RoomVacancyShutdownTimer.Cancel();
}
}
/// <summary>
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
/// </summary>
/// <param name="o"></param>
public abstract void RoomVacatedForTimeoutPeriod(object o);
}
/// <summary>
/// To describe the various ways a room may be shutting down
/// </summary>
public enum eShutdownType
{
None = 0,
External,
Manual,
Vacancy
}
public enum eVacancyMode
{
None = 0,
InInitialVacancy,
InShutdownWarning
}
/// <summary>
///
/// </summary>
public enum eWarmingCoolingMode
{
None,
Warming,
Cooling
}
public abstract class EssentialsRoomEmergencyBase : IKeyed
{
public string Key { get; private set; }
public EssentialsRoomEmergencyBase(string key)
{
Key = key;
}
}
}
/// <summary>
/// Timer used for informing the UIs of a shutdown
/// </summary>
public SecondsCountdownTimer ShutdownPromptTimer { get; private set; }
/// <summary>
///
/// </summary>
public int ShutdownPromptSeconds { get; set; }
public int ShutdownVacancySeconds { get; set; }
public eShutdownType ShutdownType { get; private set; }
public EssentialsRoomEmergencyBase Emergency { get; set; }
public Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; set; }
public string LogoUrlLightBkgnd { get; set; }
public string LogoUrlDarkBkgnd { get; set; }
protected SecondsCountdownTimer RoomVacancyShutdownTimer { get; private set; }
public eVacancyMode VacancyMode { get; private set; }
/// <summary>
/// Seconds after vacancy prompt is displayed until shutdown
/// </summary>
protected int RoomVacancyShutdownSeconds;
/// <summary>
/// Seconds after vacancy detected until prompt is displayed
/// </summary>
protected int RoomVacancyShutdownPromptSeconds;
/// <summary>
///
/// </summary>
protected abstract Func<bool> OnFeedbackFunc { get; }
protected Dictionary<IBasicVolumeWithFeedback, uint> SavedVolumeLevels = new Dictionary<IBasicVolumeWithFeedback, uint>();
/// <summary>
/// When volume control devices change, should we zero the one that we are leaving?
/// </summary>
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; private set; }
public EssentialsRoomBase(DeviceConfig config)
: base(config)
{
// Setup the ShutdownPromptTimer
ShutdownPromptTimer = new SecondsCountdownTimer(Key + "-offTimer");
ShutdownPromptTimer.IsRunningFeedback.OutputChange += (o, a) =>
{
if (!ShutdownPromptTimer.IsRunningFeedback.BoolValue)
ShutdownType = eShutdownType.None;
};
ShutdownPromptTimer.HasFinished += (o, a) => Shutdown(); // Shutdown is triggered
ShutdownPromptSeconds = 60;
ShutdownVacancySeconds = 120;
ShutdownType = eShutdownType.None;
RoomVacancyShutdownTimer = new SecondsCountdownTimer(Key + "-vacancyOffTimer");
//RoomVacancyShutdownTimer.IsRunningFeedback.OutputChange += (o, a) =>
//{
// if (!RoomVacancyShutdownTimer.IsRunningFeedback.BoolValue)
// ShutdownType = ShutdownType.Vacancy;
//};
RoomVacancyShutdownTimer.HasFinished += new EventHandler<EventArgs>(RoomVacancyShutdownPromptTimer_HasFinished); // Shutdown is triggered
RoomVacancyShutdownPromptSeconds = 1500; // 25 min to prompt warning
RoomVacancyShutdownSeconds = 240; // 4 min after prompt will trigger shutdown prompt
VacancyMode = eVacancyMode.None;
OnFeedback = new BoolFeedback(OnFeedbackFunc);
IsWarmingUpFeedback = new BoolFeedback(IsWarmingFeedbackFunc);
IsCoolingDownFeedback = new BoolFeedback(IsCoolingFeedbackFunc);
AddPostActivationAction(() =>
{
if (RoomOccupancy != null)
OnRoomOccupancyIsSet();
});
}
public override bool CustomActivate()
{
SetUpMobileControl();
return base.CustomActivate();
}
/// <summary>
/// If mobile control is enabled, sets the appropriate properties
/// </summary>
void SetUpMobileControl()
{
var mcBridgeKey = string.Format("mobileControlBridge-{0}", Key);
var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey);
if (mcBridge == null)
{
Debug.Console(1, this, "*********************Mobile Control Bridge Not found for this room.");
IsMobileControlEnabled = false;
return;
}
else
{
MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge;
Debug.Console(1, this, "*********************Mobile Control Bridge found and enabled for this room");
IsMobileControlEnabled = true;
}
}
void RoomVacancyShutdownPromptTimer_HasFinished(object sender, EventArgs e)
{
switch (VacancyMode)
{
case eVacancyMode.None:
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
break;
case eVacancyMode.InInitialVacancy:
StartRoomVacancyTimer(eVacancyMode.InShutdownWarning);
break;
case eVacancyMode.InShutdownWarning:
{
StartShutdown(eShutdownType.Vacancy);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting Down due to vacancy.");
break;
}
default:
break;
}
}
/// <summary>
///
/// </summary>
/// <param name="type"></param>
public void StartShutdown(eShutdownType type)
{
// Check for shutdowns running. Manual should override other shutdowns
if (type == eShutdownType.Manual)
ShutdownPromptTimer.SecondsToCount = ShutdownPromptSeconds;
else if (type == eShutdownType.Vacancy)
ShutdownPromptTimer.SecondsToCount = ShutdownVacancySeconds;
ShutdownType = type;
ShutdownPromptTimer.Start();
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "ShutdownPromptTimer Started. Type: {0}. Seconds: {1}", ShutdownType, ShutdownPromptTimer.SecondsToCount);
}
public void StartRoomVacancyTimer(eVacancyMode mode)
{
if (mode == eVacancyMode.None)
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownPromptSeconds;
else if (mode == eVacancyMode.InInitialVacancy)
RoomVacancyShutdownTimer.SecondsToCount = RoomVacancyShutdownSeconds;
else if (mode == eVacancyMode.InShutdownWarning)
RoomVacancyShutdownTimer.SecondsToCount = 60;
VacancyMode = mode;
RoomVacancyShutdownTimer.Start();
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Vacancy Timer Started. Mode: {0}. Seconds: {1}", VacancyMode, RoomVacancyShutdownTimer.SecondsToCount);
}
/// <summary>
/// Resets the vacancy mode and shutsdwon the room
/// </summary>
public void Shutdown()
{
VacancyMode = eVacancyMode.None;
EndShutdown();
}
/// <summary>
/// This method is for the derived class to define it's specific shutdown
/// requirements but should not be called directly. It is called by Shutdown()
/// </summary>
protected abstract void EndShutdown();
/// <summary>
/// Override this to implement a default volume level(s) method
/// </summary>
public abstract void SetDefaultLevels();
/// <summary>
/// Sets the object to be used as the IOccupancyStatusProvider for the room. Can be an Occupancy Aggregator or a specific device
/// </summary>
/// <param name="statusProvider"></param>
public void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes)
{
if (statusProvider == null)
{
Debug.Console(0, this, "ERROR: Occupancy sensor device is null");
return;
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Room Occupancy set to device: '{0}'", (statusProvider as Device).Key);
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Timeout Minutes from Config is: {0}", timeoutMinutes);
// If status provider is fusion, set flag to remote
if (statusProvider is Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase)
OccupancyStatusProviderIsRemote = true;
if(timeoutMinutes > 0)
RoomVacancyShutdownSeconds = timeoutMinutes * 60;
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "RoomVacancyShutdownSeconds set to {0}", RoomVacancyShutdownSeconds);
RoomOccupancy = statusProvider;
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange -= RoomIsOccupiedFeedback_OutputChange;
RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
OnRoomOccupancyIsSet();
}
void OnRoomOccupancyIsSet()
{
var handler = RoomOccupancyIsSet;
if (handler != null)
handler(this, new EventArgs());
}
/// <summary>
/// To allow base class to power room on to last source
/// </summary>
public abstract void PowerOnToDefaultOrLastSource();
/// <summary>
/// To allow base class to power room on to default source
/// </summary>
/// <returns></returns>
public abstract bool RunDefaultPresentRoute();
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
{
if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
// Trigger the timer when the room is vacant
StartRoomVacancyTimer(eVacancyMode.InInitialVacancy);
}
else
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Occupancy Detected");
// Reset the timer when the room is occupied
RoomVacancyShutdownTimer.Cancel();
}
}
/// <summary>
/// Executes when RoomVacancyShutdownTimer expires. Used to trigger specific room actions as needed. Must nullify the timer object when executed
/// </summary>
/// <param name="o"></param>
public abstract void RoomVacatedForTimeoutPeriod(object o);
}
/// <summary>
/// To describe the various ways a room may be shutting down
/// </summary>
public enum eShutdownType
{
None = 0,
External,
Manual,
Vacancy
}
public enum eVacancyMode
{
None = 0,
InInitialVacancy,
InShutdownWarning
}
/// <summary>
///
/// </summary>
public enum eWarmingCoolingMode
{
None,
Warming,
Cooling
}
public abstract class EssentialsRoomEmergencyBase : IKeyed
{
public string Key { get; private set; }
public EssentialsRoomEmergencyBase(string key)
{
Key = key;
}
}
}

View File

@@ -41,14 +41,6 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
/// Simplified routing direct from source to destination
/// </summary>
public interface IRunDirectRouteAction
{
void RunDirectRoute(string sourceKey, string destinationKey);
}
/// <summary>
/// For rooms that default presentation only routing
/// </summary>

View File

@@ -59,7 +59,7 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// For fixed-source endpoint devices
/// </summary>
[Obsolete("Please switch to IRoutingSink")]
[Obsolete]
public interface IRoutingSinkNoSwitching : IRoutingSink
{
@@ -92,16 +92,6 @@ namespace PepperDash.Essentials.Core
void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType);
}
public interface IRoutingWithClear : IRouting
{
/// <summary>
/// Clears a route to an output, however a device needs to do that
/// </summary>
/// <param name="outputSelector">Output to clear</param>
/// <param name="signalType">signal type to clear</param>
void ClearRoute(object outputSelector, eRoutingSignalType signalType);
}
public interface IRoutingNumeric : IRouting
{
void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type);
@@ -121,87 +111,10 @@ namespace PepperDash.Essentials.Core
IntFeedback AudioVideoSourceNumericFeedback { get; }
}
/// <summary>
/// Defines an IRmcRouting with a feedback event
/// </summary>
public interface ITxRoutingWithFeedback : ITxRouting
{
}
/// <summary>
/// Defines an IRmcRouting with a feedback event
/// </summary>
public interface IRmcRoutingWithFeedback : IRmcRouting
{
}
/// <summary>
/// <summary>
/// Defines an IRoutingOutputs devices as being a source - the start of the chain
/// </summary>
public interface IRoutingSource : IRoutingOutputs
{
}
/// <summary>
/// Defines an event structure for reporting output route data
/// </summary>
public interface IRoutingFeedback : IKeyName
{
event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
//void OnSwitchChange(RoutingNumericEventArgs e);
}
/// <summary>
/// Defines an IRoutingNumeric with a feedback event
/// </summary>
public interface IRoutingNumericWithFeedback : IRoutingNumeric, IRoutingFeedback
{
}
/// <summary>
/// Defines an IRouting with a feedback event
/// </summary>
public interface IRoutingWithFeedback : IRouting, IRoutingFeedback
{
}
public class RoutingNumericEventArgs : EventArgs
{
public uint? Output { get; set; }
public uint? Input { get; set; }
public eRoutingSignalType SigType { get; set; }
public RoutingInputPort InputPort { get; set; }
public RoutingOutputPort OutputPort { get; set; }
public RoutingNumericEventArgs(uint output, uint input, eRoutingSignalType sigType) : this(output, input, null, null, sigType)
{
}
public RoutingNumericEventArgs(RoutingOutputPort outputPort, RoutingInputPort inputPort,
eRoutingSignalType sigType)
: this(null, null, outputPort, inputPort, sigType)
{
}
public RoutingNumericEventArgs()
: this(null, null, null, null, 0)
{
}
public RoutingNumericEventArgs(uint? output, uint? input, RoutingOutputPort outputPort,
RoutingInputPort inputPort, eRoutingSignalType sigType)
{
OutputPort = outputPort;
InputPort = inputPort;
Output = output;
Input = input;
SigType = sigType;
}
}
}

View File

@@ -17,7 +17,7 @@ namespace PepperDash.Essentials.Core
public string Key { get; private set; }
public BoolFeedback IsRunningFeedback { get; private set; }
bool _isRunning;
bool _IsRunning;
public IntFeedback PercentFeedback { get; private set; }
public StringFeedback TimeRemainingFeedback { get; private set; }
@@ -32,7 +32,7 @@ namespace PepperDash.Essentials.Core
public DateTime StartTime { get; private set; }
public DateTime FinishTime { get; private set; }
private CTimer _secondTimer;
CTimer SecondTimer;
/// <summary>
/// Constructor
@@ -41,34 +41,38 @@ namespace PepperDash.Essentials.Core
public SecondsCountdownTimer(string key)
{
Key = key;
IsRunningFeedback = new BoolFeedback(() => _isRunning);
IsRunningFeedback = new BoolFeedback(() => _IsRunning);
TimeRemainingFeedback = new StringFeedback(() =>
{
// Need to handle up and down here.
if (StartTime == null || FinishTime == null)
return "";
var timeSpan = FinishTime - DateTime.Now;
Debug.Console(2, this,
"timeSpan.Minutes == {0}, timeSpan.Seconds == {1}, timeSpan.TotalSeconds == {2}",
timeSpan.Minutes, timeSpan.Seconds, timeSpan.TotalSeconds);
if (Math.Floor(timeSpan.TotalSeconds) < 60 && Math.Floor(timeSpan.TotalSeconds) >= 0) //ignore milliseconds
if (timeSpan.TotalSeconds < 60)
{
return String.Format("{0:00}", timeSpan.Seconds);
return Math.Round(timeSpan.TotalSeconds).ToString();
}
else
{
Debug.Console(2, this, "timeSpan.Minutes == {0}, timeSpan.Seconds == {1}", timeSpan.Minutes, timeSpan.Seconds);
return String.Format("{0:D2}:{1:D2}",
timeSpan.Minutes,
timeSpan.Seconds);
}
return Math.Floor(timeSpan.TotalSeconds) < 0
? "00"
: String.Format("{0:00}:{1:00}", timeSpan.Minutes, timeSpan.Seconds);
});
PercentFeedback =
new IntFeedback(
() =>
(int)
(Math.Floor((FinishTime - DateTime.Now).TotalSeconds)/
Math.Floor((FinishTime - StartTime).TotalSeconds)*100));
PercentFeedback = new IntFeedback(() =>
{
if (StartTime == null || FinishTime == null)
return 0;
double percent = (FinishTime - DateTime.Now).TotalSeconds
/ (FinishTime - StartTime).TotalSeconds
* 100;
return (int)percent;
});
}
/// <summary>
@@ -76,15 +80,15 @@ namespace PepperDash.Essentials.Core
/// </summary>
public void Start()
{
if (_isRunning)
if (_IsRunning)
return;
StartTime = DateTime.Now;
FinishTime = StartTime + TimeSpan.FromSeconds(SecondsToCount);
if (_secondTimer != null)
_secondTimer.Stop();
_secondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000);
_isRunning = true;
if (SecondTimer != null)
SecondTimer.Stop();
SecondTimer = new CTimer(SecondElapsedTimerCallback, null, 0, 1000);
_IsRunning = true;
IsRunningFeedback.FireUpdate();
var handler = HasStarted;
@@ -97,7 +101,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
public void Reset()
{
_isRunning = false;
_IsRunning = false;
Start();
}
@@ -127,22 +131,19 @@ namespace PepperDash.Essentials.Core
void StopHelper()
{
if (_secondTimer != null)
_secondTimer.Stop();
_isRunning = false;
if (SecondTimer != null)
SecondTimer.Stop();
_IsRunning = false;
IsRunningFeedback.FireUpdate();
}
void SecondElapsedTimerCallback(object o)
{
if (DateTime.Now >= FinishTime)
{
Finish();
return;
}
PercentFeedback.FireUpdate();
TimeRemainingFeedback.FireUpdate();
if (DateTime.Now >= FinishTime)
Finish();
}
}
}

View File

@@ -1,177 +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 Newtonsoft.Json;
namespace PepperDash.Essentials.Core.Timers
{
/// <summary>
/// A device that runs a retriggerable timer and can execute actions specified in config
/// </summary>
[Description("A retriggerable timer device")]
public class RetriggerableTimer : EssentialsDevice
{
private RetriggerableTimerPropertiesConfig _propertiesConfig;
private CTimer _timer;
private long _timerIntervalMs;
public RetriggerableTimer(string key, DeviceConfig config)
: base(key, config.Name)
{
var props = config.Properties.ToObject<RetriggerableTimerPropertiesConfig>();
_propertiesConfig = props;
if (_propertiesConfig != null)
{
_timerIntervalMs = _propertiesConfig.TimerIntervalMs;
}
}
public override bool CustomActivate()
{
if (_propertiesConfig.StartTimerOnActivation)
{
StartTimer();
}
return base.CustomActivate();
}
private void CleanUpTimer()
{
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
}
_timer = null;
}
public void StartTimer()
{
CleanUpTimer();
Debug.Console(0, this, "Starting Timer");
_timer = new CTimer(TimerElapsedCallback, GetActionFromConfig(eRetriggerableTimerEvents.Elapsed), _timerIntervalMs, _timerIntervalMs);
}
public void StopTimer()
{
Debug.Console(0, this, "Stopping Timer");
_timer.Stop();
ExecuteAction(GetActionFromConfig(eRetriggerableTimerEvents.Stopped));
}
private DeviceActionWrapper GetActionFromConfig(eRetriggerableTimerEvents eventType)
{
var action = _propertiesConfig.Events[eRetriggerableTimerEvents.Elapsed];
if (action != null)
return action;
else return null;
}
/// <summary>
/// Executes the Elapsed action from confing when the timer elapses
/// </summary>
/// <param name="o"></param>
private void TimerElapsedCallback(object action)
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Timer Elapsed. Executing Action");
if (action == null)
{
Debug.Console(1, this, "Timer elapsed but unable to execute action. Action is null.");
return;
}
var devAction = action as DeviceActionWrapper;
if (devAction != null)
ExecuteAction(devAction);
else
{
Debug.Console(2, this, "Unable to cast action as DeviceActionWrapper. Cannot Execute");
}
}
private void ExecuteAction(DeviceActionWrapper action)
{
if (action == null)
return;
try
{
DeviceJsonApi.DoDeviceAction(action);
}
catch (Exception e)
{
Debug.Console(2, this, "Error Executing Action: {0}", e);
}
//finally // Not sure this is needed
//{
// _Timer.Reset(0, _TimerIntervalMs);
//}
}
}
/// <summary>
/// Configuration Properties for RetriggerableTimer
/// </summary>
public class RetriggerableTimerPropertiesConfig
{
[JsonProperty("startTimerOnActivation")]
public bool StartTimerOnActivation { get; set; }
[JsonProperty("timerIntervalMs")]
public long TimerIntervalMs { get; set; }
[JsonProperty("events")]
public Dictionary<eRetriggerableTimerEvents, DeviceActionWrapper> Events { get; set; }
public RetriggerableTimerPropertiesConfig()
{
Events = new Dictionary<eRetriggerableTimerEvents, DeviceActionWrapper>();
}
}
/// <summary>
/// The set of values describing events on the timer
/// </summary>
public enum eRetriggerableTimerEvents
{
Elapsed,
Stopped,
}
/// <summary>
/// Factory class
/// </summary>
public class RetriggerableTimerFactory : EssentialsDeviceFactory<RetriggerableTimer>
{
public RetriggerableTimerFactory()
{
TypeNames = new List<string>() { "retriggerabletimer" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new RetriggerableTimer Device");
return new RetriggerableTimer(dc.Key, dc);
}
}
}

View File

@@ -169,9 +169,9 @@ namespace PepperDash.Essentials.Core.PageManagers
}
// Build presets
if (stb.HasPresets && stb.TvPresets != null)
if (stb.HasPresets && stb.PresetsModel != null)
{
PresetsView = new DevicePresetsView(trilist, stb.TvPresets);
PresetsView = new DevicePresetsView(trilist, stb.PresetsModel);
}
}

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