Compare commits

..

23 Commits

Author SHA1 Message Date
Neil Dorin
7a426ebc3a Updates factory method signature to take parent room as parameter. Adds methods to build components in ComponentRoom constructor 2021-02-01 14:20:57 -07:00
Neil Dorin
f0299729e6 Progress on abstract base classes and interfaces 2021-01-29 17:19:59 -07:00
Neil Dorin
657b9f1f54 Adds summary help and Room ActivityComponentBase 2021-01-28 18:08:06 -07:00
Neil Dorin
76a8b50b6f Updates GetComponetsofType generic 2021-01-28 17:46:12 -07:00
Neil Dorin
bee73edbe1 progress on component room classes and interfaces 2021-01-28 13:36:59 -07:00
Neil Dorin
fb97cf4753 Merge branch 'development' into feature/add-component-room 2021-01-27 14:05:28 -07:00
Neil Dorin
3fd84d1fac Removes EssentialsInterfaces library and moves interfaces to Essentials Core 2021-01-27 13:53:06 -07:00
Neil Dorin
c262e7c3c5 minor fixes to allow build to succeed. 2021-01-19 17:04:06 -07:00
Neil Dorin
7404566f72 Adds ComponentFactory 2021-01-19 17:00:52 -07:00
Neil Dorin
cb49b1f8c8 Interfaces added and some base classes built 2020-11-27 18:05:14 -07:00
Andrew Welker
de3f2004de Merge pull request #516 from PepperDash/feature-2.0.0/add-new-project
Add PepperDash_Essentials_Interfaces project
2020-11-25 10:30:16 -07:00
Andrew Welker
0cfc727b08 Fix root namespaces 2020-11-25 09:57:09 -07:00
Andrew Welker
0f8251ea8a update dependencies, references, and build order 2020-11-24 17:06:03 -07:00
Andrew Welker
13cbeb7605 Add PepperDash_Essentials_Interfaces project 2020-11-24 16:43:24 -07:00
Andrew Welker
2fd2b6787f Merge pull request #515 from PepperDash/feature-2.0.0/update-workflows-for-2.0.0
fix regex
2020-11-24 16:41:24 -07:00
Andrew Welker
dd48147fdb fix regex 2020-11-24 16:26:07 -07:00
Andrew Welker
33c3c1ad30 Merge pull request #511 from PepperDash/feature-2.0.0/update-workflows-for-2.0.0
fix branch name for PR-triggered workflows
2020-11-24 15:09:55 -07:00
Andrew Welker
f154ce2385 fix branch name for PR-triggered workflows 2020-11-24 14:32:21 -07:00
Trevor Payne
9a0cf05360 Merge pull request #509 from PepperDash/feature-2.0.0/update-workflows-for-2.0.0
Feature 2.0.0/update workflows for 2.0.0
2020-11-24 15:29:32 -06:00
Andrew Welker
d2e4be162d change phase for PR triggered builds to beta 2020-11-24 13:43:07 -07:00
Andrew Welker
9dbfd9bcae Change workflow name 2020-11-24 13:25:02 -07:00
Andrew Welker
8d1ec183df fix string formatting 2020-11-24 13:17:10 -07:00
Andrew Welker
d52941d91d add workflow for 2.0.0 builds 2020-11-24 13:14:07 -07:00
36 changed files with 2667 additions and 2254 deletions

View File

@@ -0,0 +1,23 @@
$latestVersion = [version]"2.0.0"
$newVersion = [version]$latestVersion
$phase = ""
$newVersionString = ""
switch -regex ($Env:GITHUB_REF) {
'^refs\/pull\/*.' {
$phase = 'beta';
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
'^refs\/heads\/feature-2.0.0\/*.' {
$phase = 'alpha'
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
'development-2.0.0' {
$phase = 'beta'
$newVersionString = "{0}-{1}-{2}" -f $newVersion, $phase, $Env:GITHUB_RUN_NUMBER
}
}
Write-Output $newVersionString

307
.github/workflows/Build Essentials.yml vendored Normal file
View File

@@ -0,0 +1,307 @@
name: Build Essentials 2.0.0
on:
push:
branches:
- feature-2.0.0/*
pull_request:
types:
- closed
branches:
- development-2.0.0
env:
# solution path doesn't need slashes unless there it is multiple folders deep
# solution name does not include extension. .sln is assumed
SOLUTION_PATH: PepperDashEssentials
SOLUTION_FILE: PepperDashEssentials
# Do not edit this, we're just creating it here
VERSION: 0.0.0-buildtype-buildnumber
# Defaults to debug for build type
BUILD_TYPE: Debug
# Defaults to main as the release branch. Change as necessary
RELEASE_BRANCH: main
jobs:
Build_Project:
runs-on: windows-latest
steps:
# First we checkout the source repo
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
# Fetch all tags
- name: Fetch tags
run: git fetch --tags
# Generate the appropriate version number
- name: Set Version Number
shell: powershell
run: |
$version = ./.github/scripts/GenerateVersionNumber-2.0.0.ps1
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs
shell: powershell
run: |
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
# Login to Docker
- name: Login to Docker
uses: azure/docker-login@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
# Build the solutions in the docker image
- name: Build Solution
shell: powershell
run: |
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
# Zip up the output files as needed
- name: Zip Build Output
shell: powershell
run: ./.github/scripts/ZipBuildOutput.ps1
# Write the version to a file to be consumed by the push jobs
- name: Write Version
run: Write-Output "$($Env:VERSION)" | Out-File -FilePath "$($Env:GITHUB_HOME)\output\version.txt"
# Upload the build output as an artifact
- name: Upload Build Output
uses: actions/upload-artifact@v1
with:
name: Build
path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
# Upload the Version file as an artifact
- name: Upload version.txt
uses: actions/upload-artifact@v1
with:
name: Version
path: ${{env.GITHUB_HOME}}\output\version.txt
# Create the release on the source repo
- name: Create 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 }}
release_name: ${{ env.VERSION }}
prerelease: ${{contains('debug', env.BUILD_TYPE)}}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Upload the build package to the release
- name: Upload Release Package
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
id: upload_release
uses: actions/upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_name: ${{ env.SOLUTION_FILE}}-${{ env.VERSION}}.zip
asset_content_type: application/zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Push_Nuget_Package:
needs: Build_Project
runs-on: windows-latest
steps:
- name: Download Build Version Info
uses: actions/download-artifact@v1
with:
name: Version
- name: Set Version Number
shell: powershell
run: |
Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version"
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version
- name: Download Build output
uses: actions/download-artifact@v1
with:
name: Build
path: ./
- name: Unzip Build file
run: |
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
Remove-Item -Path .\*.zip
- name: Copy Files to root & delete output directory
run: |
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
Remove-Item -Path .\output -Recurse
- name: Add nuget.exe
uses: nuget/setup-nuget@v1
- name: Add Github Packages source
run: nuget sources add -name github -source https://nuget.pkg.github.com/pepperdash/index.json -username Pepperdash -password ${{ secrets.GITHUB_TOKEN }}
- name: Add nuget.org API Key
run: nuget setApiKey ${{ secrets.NUGET_API_KEY }}
- name: Create nuget package
run: nuget pack "./PepperDash_Essentials_Core.nuspec" -version ${{ env.VERSION }}
- name: Publish nuget package to Github registry
run: nuget push **/*.nupkg -source github
- name: Publish nuget package to nuget.org
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
# This step always runs and pushes the build to the internal build rep
# Internal_Push_Output:
# needs: Build_Project
# runs-on: windows-latest
# steps:
# - name: check Github ref
# run: ${{toJson(github.ref)}}
# # Checkout the repo
# - name: Checkout Builds Repo
# uses: actions/checkout@v2
# with:
# token: ${{ secrets.BUILDS_TOKEN }}
# repository: PepperDash-Engineering/essentials-builds
# ref: ${{ Env.GITHUB_REF }}
# # Download the version artifact from the build job
# - name: Download Build Version Info
# uses: actions/download-artifact@v1
# with:
# name: Version
# - name: Check Directory
# run: Get-ChildItem "./"
# # Set the version number environment variable from the file we just downloaded
# - name: Set Version Number
# shell: powershell
# run: |
# Get-ChildItem "./Version"
# $version = Get-Content -Path ./Version/version.txt
# Write-Host "Version: $version"
# echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Remove-Item -Path ./Version/version.txt
# Remove-Item -Path ./Version
# # Checkout/Create the branch
# - name: Create new branch
# run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# # Download the build output into the repo
# - name: Download Build output
# uses: actions/download-artifact@v1
# with:
# name: Build
# path: ./
# - name: Check directory
# run: Get-ChildItem ./
# # Unzip the build package file
# - name: Unzip Build file
# run: |
# Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
# Remove-Item -Path .\*.zip
# - name: Check directory again
# run: Get-ChildItem ./
# # Copy Contents of output folder to root directory
# - name: Copy Files to root & delete output directory
# run: |
# Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
# Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
# Remove-Item -Path .\output -Recurse
# # Commits the build output to the branch and tags it with the version
# - name: Commit build output and tag the commit
# shell: powershell
# run: |
# git config user.email "actions@pepperdash.com"
# git config user.name "GitHub Actions"
# git add .
# $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
# Write-Host "Commit: $commit"
# git commit -m $commit
# git tag $($Env:VERSION)
# # Push the commit
# - name: Push to Builds Repo
# shell: powershell
# run: |
# $branch = $($Env:GITHUB_REF) -replace "refs/heads/"
# Write-Host "Branch: $branch"
# git push -u origin $($branch) --force
# # Push the tags
# - name: Push tags
# run: git push --tags origin
# - name: Check Directory
# run: Get-ChildItem ./
# # This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
# Public_Push_Output:
# needs: Build_Project
# runs-on: windows-latest
# if: contains(github.ref, 'main') || contains(github.ref, '/release/')
# steps:
# # Checkout the repo
# - name: check Github ref
# run: ${{toJson(github.ref)}}
# - name: Checkout Builds Repo
# uses: actions/checkout@v2
# with:
# token: ${{ secrets.BUILDS_TOKEN }}
# repository: PepperDash/Essentials-Builds
# ref: ${{ Env.GITHUB_REF }}
# # Download the version artifact from the build job
# - name: Download Build Version Info
# uses: actions/download-artifact@v1
# with:
# name: Version
# - name: Check Directory
# run: Get-ChildItem "./"
# # Set the version number environment variable from the file we just downloaded
# - name: Set Version Number
# shell: powershell
# run: |
# Get-ChildItem "./Version"
# $version = Get-Content -Path ./Version/version.txt
# Write-Host "Version: $version"
# echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Remove-Item -Path ./Version/version.txt
# Remove-Item -Path ./Version
# # Checkout/Create the branch
# - name: Create new branch
# run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
# # Download the build output into the repo
# - name: Download Build output
# uses: actions/download-artifact@v1
# with:
# name: Build
# path: ./
# - name: Check directory
# run: Get-ChildItem ./
# # Unzip the build package file
# - name: Unzip Build file
# run: |
# Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
# Remove-Item -Path .\*.zip
# - name: Check directory again
# run: Get-ChildItem ./
# # Copy Contents of output folder to root directory
# - name: Copy Files to root & delete output directory
# run: |
# Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
# Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
# Remove-Item -Path .\output -Recurse
# # Commits the build output to the branch and tags it with the version
# - name: Commit build output and tag the commit
# shell: powershell
# run: |
# git config user.email "actions@pepperdash.com"
# git config user.name "GitHub Actions"
# git add .
# $commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
# Write-Host "Commit: $commit"
# git commit -m $commit
# git tag $($Env:VERSION)
# # Push the commit
# - name: Push to Builds Repo
# shell: powershell
# run: |
# $branch = $($Env:GITHUB_REF) -replace "refs/heads/"
# Write-Host "Branch: $branch"
# git push -u origin $($branch) --force
# # Push the tags
# - name: Push tags
# run: git push --tags origin
# - name: Check Directory
# run: Get-ChildItem ./

View File

@@ -17,6 +17,7 @@ using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Config;
using PepperDash.Essentials.Core.Room;
using Newtonsoft.Json;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
@@ -61,6 +62,8 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.Room.Components.ComponentFactory.GetComponentFactoryTypes, "getcomponenttypes", "Gets the components types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
@@ -130,7 +133,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"
@@ -323,12 +326,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());
@@ -434,8 +432,18 @@ namespace PepperDash.Essentials
foreach (var roomConfig in ConfigReader.ConfigObject.Rooms)
{
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
if (room != null)
Device room = null;
if (roomConfig.Type.ToLower() != "componentroom")
{
room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
}
else
{
room = new ComponentRoom(roomConfig);
}
if (room != null && room is EssentialsRoomBase)
{
// default IPID
uint fusionIpId = 0xf1;
@@ -443,11 +451,14 @@ namespace PepperDash.Essentials
// default to no join map key
string fusionJoinMapKey = string.Empty;
if (room.Config.Properties["fusion"] != null)
var essRoom = room as EssentialsRoomBase;
if (essRoom.Config.Properties["fusion"] != null)
{
Debug.Console(2, "Custom Fusion config found. Using custom values");
var fusionConfig = room.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
var fusionConfig = essRoom.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
if (fusionConfig != null)
{
@@ -458,26 +469,24 @@ namespace PepperDash.Essentials
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(essRoom, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
CreateMobileControlBridge(room as EssentialsRoomBase);
}
else if (room is EssentialsHuddleVtc1Room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)essRoom, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
CreateMobileControlBridge(room as EssentialsRoomBase);
}
else if (room is EssentialsTechRoom)
{
@@ -485,18 +494,20 @@ namespace PepperDash.Essentials
Debug.Console(0, Debug.ErrorLogLevel.Notice,
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)essRoom, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
CreateMobileControlBridge(room);
CreateMobileControlBridge(essRoom);
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
}
else if (room != null)
{
DeviceManager.AddDevice(room);
}
else
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key);
@@ -593,9 +604,9 @@ namespace PepperDash.Essentials
return ((logoDark != null && logoDark == "system") ||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
}
catch
catch (Exception e)
{
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config");
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config: {0}", e);
return false;
}
}

View File

@@ -30,29 +30,27 @@ namespace PepperDash.Essentials.Fusion
foreach (var display in displays.Values.Cast<DisplayBase>())
{
var disp = display; // Local scope variable
Debug.Console(2, this, "Setting up Static Asset for {0}", display.Key);
Debug.Console(2, this, "Setting up Static Asset for {0}", disp.Key);
disp.UsageTracker = new UsageTracking(disp) { UsageIsTracked = true };
disp.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
display.UsageTracker = new UsageTracking(display) { UsageIsTracked = true };
display.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var dispPowerOnAction = new Action<bool>(b =>
{
if (!b)
{
disp.PowerOn();
display.PowerOn();
}
});
var dispPowerOffAction = new Action<bool>(b =>
{
if (!b)
{
disp.PowerOff();
display.PowerOff();
}
});
var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(disp.Key);
var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(display.Key);
FusionAsset tempAsset;
@@ -65,36 +63,30 @@ namespace PepperDash.Essentials.Fusion
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
disp.Name, "Display", "");
display.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
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;
var defaultTwoWayDisplay = display as IHasPowerControlWithFeedback;
if (defaultTwoWayDisplay != null)
{
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (disp is IDisplayUsage)
if (display is IDisplayUsage)
{
(disp as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
(display as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
}
if(dispAsset != null)
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
}
// Use extension methods
dispAsset.TrySetMakeModel(display);
dispAsset.TryLinkAssetErrorToCommunication(display);
}
}
catch (Exception e)

View File

@@ -7,7 +7,7 @@
<ProjectGuid>{1BED5BA9-88C4-4365-9362-6F4B128071D3}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepperDashEssentials</RootNamespace>
<RootNamespace>PepperDash.Essentials</RootNamespace>
<AssemblyName>PepperDashEssentials</AssemblyName>
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92230};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PlatformFamilyName>WindowsCE</PlatformFamilyName>

View File

@@ -274,23 +274,10 @@ 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)
@@ -346,6 +333,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);

View File

@@ -201,25 +201,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 +256,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);

View File

@@ -51,6 +51,20 @@ namespace PepperDash.Essentials
//************************
public override string SourceListKey
{
get
{
return _SourceListKey;
}
set
{
_SourceListKey = value;
SetCodecExternalSources();
}
}
protected override Func<bool> OnFeedbackFunc
{
get
@@ -324,8 +338,7 @@ namespace PepperDash.Essentials
CallTypeFeedback = new IntFeedback(() => 0);
SetSourceListKey();
SourceListKey = "default";
EnablePowerOnToLastSource = true;
}
catch (Exception e)
@@ -334,21 +347,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 +370,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>
@@ -600,21 +597,12 @@ namespace PepperDash.Essentials
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
{
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
VideoCodec.StandbyDeactivate();
}
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
{
VideoCodec.StandbyDeactivate();
}
else
{
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
}
}
else
{
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
}
// report back when done

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

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

@@ -246,8 +246,11 @@ namespace PepperDash.Essentials.Core
public class DeviceActionWrapper
{
[JsonProperty("deviceKey")]
public string DeviceKey { get; set; }
[JsonProperty("methodName")]
public string MethodName { get; set; }
[JsonProperty("params")]
public object[] Params { get; set; }
}

View File

@@ -1,113 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class
/// </summary>
[Description("The base Essentials Device Class")]
public abstract class EssentialsDevice : Device
{
protected EssentialsDevice(string key)
: base(key)
{
}
protected EssentialsDevice(string key, string name)
: base(key, name)
{
}
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DescriptionAttribute : Attribute
{
private string _Description;
public DescriptionAttribute(string description)
{
Debug.Console(2, "Setting Description: {0}", description);
_Description = description;
}
public string Description
{
get { return _Description; }
}
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class ConfigSnippetAttribute : Attribute
{
private string _ConfigSnippet;
public ConfigSnippetAttribute(string configSnippet)
{
Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
_ConfigSnippet = configSnippet;
}
public string ConfigSnippet
{
get { return _ConfigSnippet; }
}
}
/// <summary>
/// Devices the basic needs for a Device Factory
/// </summary>
public abstract class EssentialsDeviceFactory<T> : IDeviceFactory where T:EssentialsDevice
{
#region IDeviceFactory Members
/// <summary>
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
/// </summary>
public List<string> TypeNames { get; protected set; }
/// <summary>
/// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list
/// </summary>
public void LoadTypeFactories()
{
foreach (var typeName in TypeNames)
{
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Defines the basic needs for an EssentialsDevice to enable it to be build by an IDeviceFactory class
/// </summary>
[Description("The base Essentials Device Class")]
public abstract class EssentialsDevice : Device
{
protected EssentialsDevice(string key)
: base(key)
{
}
protected EssentialsDevice(string key, string name)
: base(key, name)
{
}
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DescriptionAttribute : Attribute
{
private string _Description;
public DescriptionAttribute(string description)
{
Debug.Console(2, "Setting Description: {0}", description);
_Description = description;
}
public string Description
{
get { return _Description; }
}
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class ConfigSnippetAttribute : Attribute
{
private string _ConfigSnippet;
public ConfigSnippetAttribute(string configSnippet)
{
Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
_ConfigSnippet = configSnippet;
}
public string ConfigSnippet
{
get { return _ConfigSnippet; }
}
}
/// <summary>
/// Defines the basic needs for a Device Factory
/// </summary>
public abstract class EssentialsDeviceFactory<T> : IDeviceFactory where T:EssentialsDevice
{
/// <summary>
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
/// </summary>
public List<string> TypeNames { get; protected set; }
#region IDeviceFactory Members
/// <summary>
/// Loads an item to the DeviceFactory.FactoryMethods dictionary for each entry in the TypeNames list
/// </summary>
public void LoadTypeFactories()
{
foreach (var typeName in TypeNames)
{
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute[0].Description;
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
}
}
/// <summary>
/// The method that will build the device
/// </summary>
/// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns>
public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
#endregion
}
/// <summary>
/// Devices the basic needs for a Device Factory
/// </summary>
public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice
{
/// <summary>
/// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33")
/// </summary>
public string MinimumEssentialsFrameworkVersion { get; protected set; }
}
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
DeviceFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildDevice);
}
}
#endregion
/// <summary>
/// The method that will build the device
/// </summary>
/// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns>
public abstract EssentialsDevice BuildDevice(DeviceConfig dc);
}
/// <summary>
/// Defines the basic needs for a Device Factory
/// </summary>
public abstract class EssentialsPluginDeviceFactory<T> : EssentialsDeviceFactory<T>, IPluginDeviceFactory where T : EssentialsDevice
{
/// <summary>
/// Specifies the minimum version of Essentials required for a plugin to run. Must use the format Major.Minor.Build (ex. "1.4.33")
/// </summary>
public string MinimumEssentialsFrameworkVersion { get; protected set; }
}
}

View File

@@ -16,7 +16,7 @@ namespace PepperDash.Essentials.Core
public interface IDeviceFactory
{
/// <summary>
/// Loads all the types to the DeviceFactory
/// Loads all the types to the Factory
/// </summary>
void LoadTypeFactories();
}

View File

@@ -1676,46 +1676,20 @@ namespace PepperDash.Essentials.Core.Fusion
public static FusionStaticAsset CreateStaticAsset(this FusionRoom fr, uint number, string name, string type,
string instanceId)
{
try
{
Debug.Console(0, "Adding Fusion Static Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId);
Debug.Console(0, "Adding Fusion Static Asset '{0}' to slot {1} with GUID: '{2}'", name, number, instanceId);
fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
}
catch (InvalidOperationException ex)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Error creating Static Asset for device: '{0}'. Check that multiple devices don't have missing or duplicate uid properties in configuration. /r/nError: {1}", name, ex);
return null;
}
catch (Exception e)
{
Debug.Console(2, Debug.ErrorLogLevel.Error, "Error creating Static Asset: {0}", e);
return null;
}
fr.AddAsset(eAssetType.StaticAsset, number, name, type, instanceId);
return fr.UserConfigurableAssetDetails[number].Asset as FusionStaticAsset;
}
public static FusionOccupancySensor CreateOccupancySensorAsset(this FusionRoom fr, uint number, string name,
string type, string instanceId)
{
try
{
Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number,
instanceId);
Debug.Console(0, "Adding Fusion Occupancy Sensor Asset '{0}' to slot {1} with GUID: '{2}'", name, number,
instanceId);
fr.AddAsset(eAssetType.OccupancySensor, number, name, type, instanceId);
return fr.UserConfigurableAssetDetails[number].Asset as FusionOccupancySensor;
}
catch (InvalidOperationException ex)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Error creating Static Asset for device: '{0}'. Check that multiple devices don't have missing or duplicate uid properties in configuration. Error: {1}", name, ex);
return null;
}
catch (Exception e)
{
Debug.Console(2, Debug.ErrorLogLevel.Error, "Error creating Static Asset: {0}", e);
return null;
}
fr.AddAsset(eAssetType.OccupancySensor, number, name, type, instanceId);
return fr.UserConfigurableAssetDetails[number].Asset as FusionOccupancySensor;
}
}

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

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core.Interfaces.Components
{
/// <summary>
/// Describes a room comprised of components
/// </summary>
public interface IComponentRoom : IKeyed
{
List<IActivatableComponent> Components { get; }
List<IRoomActivityComponent> Activities { get; }
List<T> GetComponentsOfType<T>() where T : IActivatableComponent;
List<IRoomActivityComponent> GetOrderedActvities();
}
/// <summary>
/// Describes a component
/// </summary>
public interface IComponent : IKeyed
{
}
/// <summary>
/// Describes a room component
/// </summary>
public interface IRoomComponent : IComponent
{
IComponentRoom Parent { get; }
}
/// <summary>
/// Describes a room activity component
/// </summary>
public interface IRoomActivityComponent : IRoomComponent
{
/// <summary>
/// Indicates if the component is enabled
/// </summary>
BoolFeedback IsEnabledFeedback { get; }
/// <summary>
/// Set this value to enable or disable the component
/// </summary>
bool Enable { set; }
/// <summary>
/// Label to be displayed for the activity on the UI
/// </summary>
string Label { get; }
/// <summary>
/// Icon to be displayed for the activity on the UI
/// </summary>
string Icon { get; }
/// <summary>
/// The component group that will be activated when this activty starts
/// </summary>
IRoomBehaviourGroupComponent Component { get; }
/// <summary>
/// Determines the order the activities will be displayed on the UI
/// </summary>
int Order { get; }
/// <summary>
/// Starts the activity
/// </summary>
void StartActivity();
/// <summary>
/// Ends the activity
/// </summary>
void EndActivity();
}
/// <summary>
/// Describes a room component that can be "activated"
/// </summary>
public interface IActivatableComponent : IRoomComponent
{
/// <summary>
/// Indicates if the component is activated
/// </summary>
BoolFeedback ActivatedFeedback { get; }
/// <summary>
/// Activates the component
/// </summary>
void Activate();
/// <summary>
/// Dactivates the component
/// </summary>
void Deactivate();
}
/// <summary>
/// Describes a group of room behaviour component. Is able to contain a collection of components that aggregate
/// together to behave as one
/// </summary>
public interface IRoomBehaviourGroupComponent
{
/// <summary>
/// A collection of components that work together to achieve a common behaviour
/// </summary>
List<IActivatableComponent> Components { get; }
void ActivateComponents();
void DeactivateComponents();
}
/// <summary>
/// Describes an individual room behaviour component
/// </summary>
public interface IRoomBehaviourComponent : IActivatableComponent
{
}
/// <summary>
/// Describes a room device component behaviour
/// </summary>
public interface IDeviceBehaviourComponent<T> : IActivatableComponent where T : EssentialsDevice
{
/// <summary>
/// The device this component applies behaviour to
/// </summary>
T Device { get; }
}
}

View File

@@ -13,586 +13,448 @@ 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 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; }
public GlsOccupancySensorBase OccSensor { get; private set; }
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;
}
}
public GlsOccupancySensorBaseController(string key, Func<DeviceConfig, GlsOccupancySensorBase> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
var props = config.Properties.ToObject<GlsOccupancySensorPropertiesConfig>();
if (props != null)
public Func<bool> RoomIsOccupiedFeedbackFunc
{
get
{
PropertiesConfig = props;
}
else
{
Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig");
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
}
}
AddPreActivationAction(() =>
{
OccSensor = preActivationFunc(config);
RegisterCrestronGenericBase(OccSensor);
RegisterGlsOdtSensorBaseController(OccSensor);
});
AddPostActivationAction(() =>
{
OccSensor.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
{
ApplySettingsToSensorFromConfig();
}
};
});
}
public GlsOccupancySensorBaseController(string key, string name, DeviceConfig config)
: base(key, name)
public GlsOccupancySensorBaseController(string key, Func<DeviceConfig, GlsOccupancySensorBase> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
var props = config.Properties.ToObject<GlsOccupancySensorPropertiesConfig>();
if (props != null)
AddPreActivationAction(() =>
{
PropertiesConfig = props;
}
else
{
Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig");
}
OccSensor = preActivationFunc(config);
AddPostActivationAction(() =>
{
OccSensor.OnlineStatusChange += (o, a) =>
{
if (a.DeviceOnLine)
{
ApplySettingsToSensorFromConfig();
}
};
RegisterCrestronGenericBase(OccSensor);
if (OccSensor.IsOnline)
{
ApplySettingsToSensorFromConfig();
RegisterGlsOdtSensorBaseController(OccSensor);
}
});
});
}
public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {}
protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor)
{
OccSensor = occSensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
PirSensitivityInVacantStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
PirSensitivityInOccupiedStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
GraceOccupancyDetectedFeedback =
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
OccSensor.BaseEvent += OccSensor_BaseEvent;
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
}
/// <summary>
/// Applies any sensor settings defined in config
/// 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>
protected virtual void ApplySettingsToSensorFromConfig()
/// <param name="device"></param>
/// <param name="args"></param>
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
Debug.Console(1, this, "Attempting to apply settings to sensor from config");
if (PropertiesConfig.EnablePir != null)
switch (args.EventId)
{
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);
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 void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor)
{
OccSensor = occSensor;
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
PirSensitivityInVacantStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
PirSensitivityInOccupiedStateFeedback =
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
GraceOccupancyDetectedFeedback =
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
OccSensor.BaseEvent += OccSensor_BaseEvent;
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
}
/// <summary>
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
/// </summary>
/// <param name="device"></param>
/// <param name="args"></param>
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
{
switch (args.EventId)
{
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
PirSensorEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
LedFlashEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
ShortTimeoutEnabledFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
PirSensitivityInOccupiedStateFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
PirSensitivityInVacantStateFeedback.FireUpdate();
break;
}
}
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
{
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
switch (args.EventId)
{
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId:
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
RoomIsOccupiedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
CurrentTimeoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
LocalTimoutFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
GraceOccupancyDetectedFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
RawOccupancyFeedback.FireUpdate();
break;
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
InternalPhotoSensorValue.FireUpdate();
break;
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
ExternalPhotoSensorValue.FireUpdate();
break;
}
}
public void SetTestMode(bool mode)
{
InTestMode = mode;
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
}
public void SetTestOccupiedState(bool state)
{
if (!InTestMode)
Debug.Console(1, "Mock mode not enabled");
else
{
TestRoomIsOccupiedFeedback = state;
RoomIsOccupiedFeedback.FireUpdate();
}
}
/// <summary>
/// Enables or disables the PIR sensor
/// </summary>
/// <param name="state"></param>
public void SetPirEnable(bool state)
{
Debug.Console(1, this, "Setting EnablePir to: {0}", 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)
{
Debug.Console(1, this, "Setting RemoteTimout to: {0}", time);
OccSensor.RemoteTimeout.UShortValue = time;
}
public void SetInternalPhotoSensorMinChange(ushort value)
{
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
}
public void SetExternalPhotoSensorMinChange(ushort value)
{
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
}
/// <summary>
/// Method to print current occ settings to console.
/// </summary>
/// <param name="key"></param>
public virtual void GetSettings()
{
var dash = new string('*', 50);
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
Debug.Console(0, this, "Vacancy Detected: {0}",
OccSensor.VacancyDetectedFeedback.BoolValue);
Debug.Console(0, this, "Timeout Current: {0} | Local: {1}",
OccSensor.CurrentTimeoutFeedback.UShortValue,
OccSensor.LocalTimeoutFeedback.UShortValue);
Debug.Console(0, this, "Short Timeout Enabled: {0}",
OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
Debug.Console(0, this, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}",
OccSensor.PirEnabledFeedback.BoolValue,
OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue,
OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
}
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
#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);
}
}
}
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

@@ -13,266 +13,206 @@ 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
{
public new GlsOdtCCn OccSensor { get; private set; }
{
public new GlsOdtCCn OccSensor { get; private set; }
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
public BoolFeedback OrWhenVacatedFeedback { get; private set; }
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
public BoolFeedback AndWhenVacatedFeedback { get; private set; }
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicAEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
public BoolFeedback UltrasonicBEnabledFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInVacantStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public IntFeedback UltrasonicSensitivityInOccupiedStateFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyPirFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
public BoolFeedback RawOccupancyUsFeedback { get; private set; }
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
DeviceConfig config)
: base(key, config.Name, config)
{
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);
});
}
protected override void ApplySettingsToSensorFromConfig()
public GlsOdtOccupancySensorController(string key, Func<DeviceConfig, GlsOdtCCn> preActivationFunc,
DeviceConfig config)
: base(key, config.Name)
{
base.ApplySettingsToSensorFromConfig();
if (PropertiesConfig.EnableUsA != null)
AddPreActivationAction(() =>
{
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");
}
OccSensor = preActivationFunc(config);
RegisterCrestronGenericBase(OccSensor);
if (PropertiesConfig.EnableUsB != null)
{
Debug.Console(1, this, "EnableUsB found, attempting to set value from config");
SetUsBEnable((bool)PropertiesConfig.EnableUsB);
}
else
{
Debug.Console(1, this, "EnablePir null, no value specified in config");
}
RegisterGlsOdtSensorBaseController(OccSensor);
AndWhenVacatedFeedback = new BoolFeedback(() => OccSensor.AndWhenVacatedFeedback.BoolValue);
if (PropertiesConfig.OrWhenVacatedState != null)
{
SetOrWhenVacatedState((bool)PropertiesConfig.OrWhenVacatedState);
}
OrWhenVacatedFeedback = new BoolFeedback(() => OccSensor.OrWhenVacatedFeedback.BoolValue);
if (PropertiesConfig.AndWhenVacatedState != null)
{
SetAndWhenVacatedState((bool)PropertiesConfig.AndWhenVacatedState);
}
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();
/// <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);
}
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();
/// <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);
}
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 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>
/// 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 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;
}
/// <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 IncrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInOccupiedState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInOccupiedState.BoolValue = pressRelease;
}
public void IncrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public void IncrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.IncrementUsSensitivityInVacantState.BoolValue = pressRelease;
}
public void DecrementUsSensitivityInVacantState(bool pressRelease)
{
OccSensor.DecrementUsSensitivityInVacantState.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);
}
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();
#region PreActivation
Debug.Console(0, this, "Ultrasonic Enabled A: {0} | B: {1}",
OccSensor.UsAEnabledFeedback.BoolValue,
OccSensor.UsBEnabledFeedback.BoolValue);
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;
Debug.Console(0, this, "Ultrasonic Sensitivity Occupied: {0} | Vacant: {1}",
OccSensor.UsSensitivityInOccupiedStateFeedback.UShortValue,
OccSensor.UsSensitivityInVacantStateFeedback.UShortValue);
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey);
return new GlsOdtCCn(cresnetId, Global.ControlSystem);
}
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
var dash = new string('*', 50);
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
}
if (cresnetBridge != null)
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey);
return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
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" };
}
#region PreActivation
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
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;
return new GlsOdtOccupancySensorController(dc.Key, GetGlsOdtCCn, dc);
}
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
{
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOdtCCn", parentKey);
return new GlsOdtCCn(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 GlsOdtCCn", parentKey);
return new GlsOdtCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
}
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

@@ -7,7 +7,7 @@
<ProjectGuid>{A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepperDash_Essentials_Core</RootNamespace>
<RootNamespace>PepperDash.Essentials.Core</RootNamespace>
<AssemblyName>PepperDash_Essentials_Core</AssemblyName>
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92300};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
@@ -225,9 +225,9 @@
<Compile Include="Gateways\CenRfgwController.cs" />
<Compile Include="Gateways\EssentialsRfGatewayConfig.cs" />
<Compile Include="Global\EthernetAdapterInfo.cs" />
<Compile Include="Interfaces\Components\RoomComponents.cs" />
<Compile Include="Interfaces\ILogStrings.cs" />
<Compile Include="Interfaces\ILogStringsWithLevel.cs" />
<Compile Include="Occupancy\GlsOccupancySensorPropertiesConfig.cs" />
<Compile Include="Queues\ComsMessage.cs" />
<Compile Include="Queues\ProcessStringMessage.cs" />
<Compile Include="Queues\GenericQueue.cs" />
@@ -282,10 +282,14 @@
<Compile Include="Remotes\CrestronRemotePropertiesConfig.cs" />
<Compile Include="Remotes\Hrxx0WirelessRemoteController.cs" />
<Compile Include="Room\Behaviours\RoomOnToDefaultSourceWhenOccupied.cs" />
<Compile Include="Room\Components\ComponentFactory.cs" />
<Compile Include="Room\Components\ComponentRoom.cs" />
<Compile Include="Room\Components\RoomComponentBase.cs" />
<Compile Include="Room\EssentialsRoomBase.cs" />
<Compile Include="Room\Config\EssentialsRoomScheduledEventsConfig.cs" />
<Compile Include="Room\Interfaces.cs" />
<Compile Include="Room\iOccupancyStatusProvider.cs" />
<Compile Include="Room\RoomFactory.cs" />
<Compile Include="Routing\DummyRoutingInputsDevice.cs" />
<Compile Include="Routing\ICardPortsDevice.cs" />
<Compile Include="InUseTracking\IInUseTracking.cs" />

View File

@@ -18,52 +18,42 @@ namespace PepperDash_Essentials_Core.Queues
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)
: this(key, Thread.eThreadPriority.MediumPriority)
{
}
/// <summary>
/// Constructor with queue size
/// Constructor for generic queue with no pacing
/// </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)
/// <param name="key">Key</param>
/// <param name="priority"></param>
public GenericQueue(string key, Thread.eThreadPriority priority)
{
_key = key;
_queue = new CrestronQueue<IQueueMessage>(25);
_worker = new Thread(ProcessQueue, null, Thread.eThreadStartOptions.Running)
{
Priority = priority
};
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
if (programEvent != eProgramStatusEventType.Stopping)
return;
Dispose();
};
}
/// <summary>
@@ -71,20 +61,10 @@ namespace PepperDash_Essentials_Core.Queues
/// </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)
public GenericQueue(string key, int pacing)
: this(key)
{
SetDelayValues(pacing);
}
/// <summary>
@@ -94,52 +74,8 @@ namespace PepperDash_Essentials_Core.Queues
/// <param name="pacing"></param>
/// <param name="priority"></param>
public GenericQueue(string key, int pacing, Thread.eThreadPriority priority)
: this(key, priority, 0, pacing)
: this(key, priority)
{
}
/// <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>
private 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);
}
@@ -147,14 +83,6 @@ namespace PepperDash_Essentials_Core.Queues
{
_delayEnabled = pacing > 0;
_delayTime = pacing;
CrestronEnvironment.ProgramStatusEventHandler += programEvent =>
{
if (programEvent != eProgramStatusEventType.Stopping)
return;
Dispose();
};
}
/// <summary>

View File

@@ -0,0 +1,194 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection;
using PepperDash.Core;
using PepperDash.Essentials.Core.Interfaces.Components;
namespace PepperDash.Essentials.Core.Room.Components
{
public class ComponentFactoryWrapper
{
public CType CType { get; set; }
public string Description { get; set; }
public Func<RoomComponentConfig, IComponentRoom, IKeyed> FactoryMethod { get; set; }
public ComponentFactoryWrapper()
{
CType = null;
Description = "Not Available";
}
}
/// <summary>
/// Defines a class that is capable of loading component types
/// </summary>
public interface IComponentFactory : IDeviceFactory
{
}
public static class ComponentFactory
{
static ComponentFactory()
{
var assy = Assembly.GetExecutingAssembly();
PluginLoader.SetEssentialsAssembly(assy.GetName().Name, assy);
var types = assy.GetTypes().Where(ct => typeof(IComponentFactory).IsAssignableFrom(ct) && !ct.IsInterface && !ct.IsAbstract);
if (types != null)
{
foreach (var type in types)
{
try
{
var factory = (IComponentFactory)Crestron.SimplSharp.Reflection.Activator.CreateInstance(type);
factory.LoadTypeFactories();
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to load type: '{1}' ComponentFactory: {0}", e, type.Name);
}
}
}
}
/// <summary>
/// A dictionary of factory methods, keyed by config types, added by plugins.
/// These methods are looked up and called by GetDevice in this class.
/// </summary>
static Dictionary<string, ComponentFactoryWrapper> FactoryMethods =
new Dictionary<string, ComponentFactoryWrapper>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Adds a plugin factory method
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static void AddFactoryForType(string typeName, Func<RoomComponentConfig, IComponentRoom, IKeyed> method)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
ComponentFactory.FactoryMethods.Add(typeName, new ComponentFactoryWrapper() { FactoryMethod = method });
}
public static void AddFactoryForType(string typeName, string description, CType cType, Func<RoomComponentConfig, IComponentRoom, IKeyed> method)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
if (FactoryMethods.ContainsKey(typeName))
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to add type: '{0}'. Already exists in ComponentFactory", typeName);
return;
}
var wrapper = new ComponentFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
ComponentFactory.FactoryMethods.Add(typeName, wrapper);
}
/// <summary>
/// The factory method for Core components. Also iterates the Factory methods that have
/// been loaded from plugins
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static IKeyed GetComponent(RoomComponentConfig dc, IComponentRoom parent)
{
var key = dc.Key;
var name = dc.Name;
var type = dc.Type;
var properties = dc.Properties;
var typeName = dc.Type.ToLower();
// Check for types that have been added by plugin dlls.
if (FactoryMethods.ContainsKey(typeName))
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
return FactoryMethods[typeName].FactoryMethod(dc, parent);
}
return null;
}
/// <summary>
/// Prints the type names and associated metadata from the FactoryMethods collection.
/// </summary>
/// <param name="command"></param>
public static void GetComponentFactoryTypes(string filter)
{
Dictionary<string, ComponentFactoryWrapper> types = new Dictionary<string, ComponentFactoryWrapper>();
if (!string.IsNullOrEmpty(filter))
{
types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
}
else
{
types = FactoryMethods;
}
Debug.Console(0, "Component Types:");
foreach (var type in types.OrderBy(t => t.Key))
{
var description = type.Value.Description;
var cType = "Not Specified by Plugin";
if (type.Value.CType != null)
{
cType = type.Value.CType.FullName;
}
Debug.Console(0,
@"Type: '{0}'
CType: '{1}'
Description: {2}", type.Key, cType, description);
}
}
}
/// <summary>
/// Devices the basic needs for a Device Factory
/// </summary>
public abstract class EssentialsComponentFactory<T> : IComponentFactory where T : IComponent
{
#region IComponentFactory Members
/// <summary>
/// A list of strings that can be used in the type property of a DeviceConfig object to build an instance of this device
/// </summary>
public List<string> TypeNames { get; protected set; }
/// <summary>
/// Loads an item to the ComponentFactory.FactoryMethods dictionary for each entry in the TypeNames list
/// </summary>
public void LoadTypeFactories()
{
foreach (var typeName in TypeNames)
{
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute[0].Description;
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];
ComponentFactory.AddFactoryForType(typeName.ToLower(), description, typeof(T), BuildComponent);
}
}
/// <summary>
/// The method that will build the device
/// </summary>
/// <param name="dc">The device config</param>
/// <returns>An instance of the device</returns>
public abstract IComponent BuildComponent(RoomComponentConfig dc, IComponentRoom parent);
#endregion
}
}

View File

@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core.Interfaces.Components;
using PepperDash.Essentials.Core.Room.Components;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Devices;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Core.Room
{
/// <summary>
/// The base config class for various component types
/// </summary>
public abstract class RoomComponentConfig : DeviceConfig
{
}
/// <summary>
/// The config class for an activiry
/// </summary>
public class RoomActivityConfig : RoomComponentConfig
{
[JsonProperty("label")]
public string Label { get; set; }
[JsonProperty("icon")]
public string Icon { get; set; }
[JsonProperty("componentKey")]
public string ComponentKey { get; set; }
[JsonProperty("order")]
public int Order { get; set; }
[JsonProperty("selectAction")]
public DeviceActionWrapper SelectAction { get; set; }
}
/// <summary>
/// The config class for a room behaviour
/// </summary>
public class RoomBehaviourConfig : RoomComponentConfig
{
}
/// <summary>
/// The config class for a device behavior
/// </summary>
public class RoomDeviceBehaviourConfig : RoomComponentConfig
{
[JsonProperty("deviceKey")]
public string DeviceKey { get; set; }
}
/// <summary>
/// The config class for a ComponentRoom
/// </summary>
public class ComponentRoomPropertiesConfig
{
[JsonProperty("activities")]
public List<RoomActivityConfig> Activities { get; set; }
[JsonProperty("components")]
public List<RoomComponentConfig> Components { get; set; }
}
/// <summary>
/// A room comprised of component parts built at runtime.
/// </summary>
public class ComponentRoom : ReconfigurableDevice, IComponentRoom
{
public ComponentRoomPropertiesConfig PropertiesConfig { get; private set; }
public List<IActivatableComponent> Components { get; private set; }
public List<IRoomActivityComponent> Activities { get; private set; }
public ComponentRoom(DeviceConfig config)
: base(config)
{
try
{
PropertiesConfig = config.Properties.ToObject<ComponentRoomPropertiesConfig>();
BuildComponents();
BuildActivities();
}
catch (Exception e)
{
Debug.Console(1, this, "Error building ComponentRoom: \n{0}", e);
}
}
private void BuildComponents()
{
foreach (var compConf in PropertiesConfig.Components)
{
IKeyed newComponent = null;
newComponent = ComponentFactory.GetComponent(compConf, this);
if (newComponent != null)
{
Components.Add(newComponent as IActivatableComponent);
DeviceManager.AddDevice(newComponent);
}
else
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Unable to build room component with key: {0}", compConf.Key);
}
}
}
private void BuildActivities()
{
foreach (var compConf in PropertiesConfig.Activities)
{
IKeyed newComponent = null;
newComponent = ComponentFactory.GetComponent(compConf, this);
if (newComponent != null)
{
Activities.Add(newComponent as IRoomActivityComponent);
DeviceManager.AddDevice(newComponent);
}
else
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Unable to build room activity with key: {0}", compConf.Key);
}
}
}
/// <summary>
/// Returns a set of IRoomComponent that matches the specified Type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public List<T> GetComponentsOfType<T>() where T : IActivatableComponent
{
return Components.OfType<T>().ToList();
}
/// <summary>
/// Returns a list of the activies sorted by order
/// </summary>
/// <returns></returns>
public List<IRoomActivityComponent> GetOrderedActvities()
{
return Activities.OrderBy(a => a.Order).ToList<IRoomActivityComponent>();
}
}
}

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Interfaces.Components;
namespace PepperDash.Essentials.Core.Room.Components
{
/// <summary>
/// The base class from which Room Components should be derived
/// </summary>
[Description("The base Essentials Device Class")]
public abstract class RoomComponentBase : IRoomComponent
{
private string _componentKey;
/// <summary>
/// The key of the component, which is composed of the parent room key, plus the specific component key
/// </summary>
public string Key {
get
{
return Parent.Key + "-" + _componentKey;
}
}
public IComponentRoom Parent { get; private set; }
public RoomComponentBase(string key, IComponentRoom parent)
{
_componentKey = key;
Parent = parent;
}
}
/// <summary>
/// The base class from which Room Activities should be derived
/// </summary>
public abstract class RoomActivityComponentBase : IRoomActivityComponent
{
#region IRoomActivityComponent Members
public BoolFeedback IsEnabledFeedback { get; private set; }
private bool _enable;
public bool Enable
{
set
{
if (value != _enable)
{
_enable = value;
IsEnabledFeedback.FireUpdate();
}
}
}
public string Label { get; private set; }
public string Icon { get; private set; }
public IRoomBehaviourGroupComponent Component { get; private set; }
public int Order { get; private set; }
#endregion
#region IRoomComponent Members
public IComponentRoom Parent { get; private set; }
#endregion
#region IKeyed Members
private string _componentKey;
public string Key
{
get
{
return Parent.Key + "-" + _componentKey;
}
}
#endregion
public RoomActivityComponentBase(string key, IComponentRoom parent)
{
_componentKey = key;
Parent = parent;
IsEnabledFeedback = new BoolFeedback(() => _enable);
}
public void StartActivity()
{
throw new NotImplementedException();
}
public void EndActivity()
{
throw new NotImplementedException();
}
}
}

View File

@@ -53,22 +53,18 @@ namespace PepperDash.Essentials.Core
/// </summary>
///
protected string _SourceListKey;
public 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>
@@ -164,22 +160,6 @@ namespace PepperDash.Essentials.Core
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>

View File

@@ -12,45 +12,45 @@ namespace PepperDash.Essentials.Core
{
//***************************************************************************************************
public abstract class Room : Device, IHasFeedback
{
public abstract BoolFeedback RoomIsOnFeedback { get; protected set; }
public abstract BoolFeedback IsCoolingDownFeedback { get; protected set; }
public abstract BoolFeedback IsWarmingUpFeedback { get; protected set; }
// public abstract class Room : Device, IHasFeedback
// {
// public abstract BoolFeedback RoomIsOnFeedback { get; protected set; }
// public abstract BoolFeedback IsCoolingDownFeedback { get; protected set; }
// public abstract BoolFeedback IsWarmingUpFeedback { get; protected set; }
// In concrete classes, these should be computed from the relevant devices
public virtual uint CooldownTime { get { return 10000; } }
public virtual uint WarmupTime { get { return 5000; } }
// // In concrete classes, these should be computed from the relevant devices
// public virtual uint CooldownTime { get { return 10000; } }
// public virtual uint WarmupTime { get { return 5000; } }
public string Description { get; set; }
public string HelpMessage { get; set; }
// public string Description { get; set; }
// public string HelpMessage { get; set; }
public Room(string key, string name)
: base(key, name)
{
Description = "";
HelpMessage = "";
}
// public Room(string key, string name)
// : base(key, name)
// {
// Description = "";
// HelpMessage = "";
// }
public virtual void RoomOn() { }
// public virtual void RoomOn() { }
public virtual void RoomOff() { }
// public virtual void RoomOff() { }
#region IDeviceWithOutputs Members
// #region IDeviceWithOutputs Members
public virtual FeedbackCollection<Feedback> Feedbacks
{
get
{
return new FeedbackCollection<Feedback>
{
RoomIsOnFeedback,
IsCoolingDownFeedback,
IsWarmingUpFeedback
};
}
}
// public virtual FeedbackCollection<Feedback> Feedbacks
// {
// get
// {
// return new FeedbackCollection<Feedback>
// {
// RoomIsOnFeedback,
// IsCoolingDownFeedback,
// IsWarmingUpFeedback
// };
// }
// }
#endregion
}
// #endregion
// }
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core.Interfaces.Components;
namespace PepperDash.Essentials.Core.Room
{
/// <summary>
/// The class that constructs rooms
/// </summary>
public static class RoomFactory
{
}
}

View File

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

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

View File

@@ -18,8 +18,8 @@ namespace PepperDash.Essentials.Core.PageManagers
{
SetTopBox = stb;
TriList = trilist;
if(stb.TvPresets != null)
PresetsView = new DevicePresetsView(trilist, stb.TvPresets);
if(stb.PresetsModel != null)
PresetsView = new DevicePresetsView(trilist, stb.PresetsModel);
}
public override void Show()

View File

@@ -44,7 +44,7 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
DeviceInfo = new DeviceInfo();
_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
//_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
_dc = dc;
@@ -123,56 +123,29 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
gather.LineReceived += (sender, args) =>
{
try
if (args.Text.ToLower().Contains("host"))
{
Debug.Console(1, this, "{0}", args.Text);
DeviceInfo.HostName = args.Text.Split(';')[1].Trim();
if (args.Text.ToLower().Contains("host"))
{
DeviceInfo.HostName = args.Text.Split(':')[1].Trim();
Debug.Console(1, this, "hostname: {0}", DeviceInfo.HostName);
tcpClient.Disconnect();
return;
}
//ignore console prompt
/*if (args.Text.ToLower().Contains(">"))
{
Debug.Console(1, this, "Ignoring console");
return;
}
if (args.Text.ToLower().Contains("dge"))
{
Debug.Console(1, this, "Ignoring DGE");
return;
}*/
if (!args.Text.Contains('['))
{
return;
}
var splitResponse = args.Text.Split('[');
foreach (string t in splitResponse)
{
Debug.Console(1, this, "{0}", t);
}
DeviceInfo.SerialNumber = splitResponse[1].Split(' ')[4].Replace("#", "");
DeviceInfo.FirmwareVersion = splitResponse[1].Split(' ')[0];
Debug.Console(1, this, "Firmware: {0} SerialNumber: {1}", DeviceInfo.FirmwareVersion,
DeviceInfo.SerialNumber);
tcpClient.SendText("host\r\n");
tcpClient.Disconnect();
return;
}
catch (Exception ex)
//ignore console prompt
if (args.Text.ToLower().Contains(">"))
{
Debug.Console(0, this, "Exception getting data: {0}", ex.Message);
Debug.Console(0, this, "response: {0}", args.Text);
return;
}
if (!args.Text.ToLower().Contains("dge"))
{
return;
}
DeviceInfo.SerialNumber = args.Text.Split('[')[1].Split(' ')[4].Replace("#", "");
DeviceInfo.FirmwareVersion = args.Text.Split('[')[1].Split(' ')[1];
tcpClient.SendText("host\r\n");
};
tcpClient.Connect();

View File

@@ -1,46 +1,46 @@
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.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM
{
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.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM
{
using eVst = DmTx401C.eSourceSelection;
[Description("Wrapper class for DM-TX-401-C")]
public class DmTx401CController : DmTxControllerBase, ITxRoutingWithFeedback, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
{
public DmTx401C Tx { get; private set; }
public RoutingInputPortWithVideoStatuses HdmiIn { get; private set; }
public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; }
public RoutingInputPortWithVideoStatuses VgaIn { get; private set; }
public RoutingInputPortWithVideoStatuses CompositeIn { get; private set; }
public RoutingOutputPort DmOut { get; private set; }
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
public BoolFeedback HdmiVideoSyncFeedback { get; protected set; }
public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; }
public class DmTx401CController : DmTxControllerBase, ITxRoutingWithFeedback, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
{
public DmTx401C Tx { get; private set; }
public RoutingInputPortWithVideoStatuses HdmiIn { get; private set; }
public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; }
public RoutingInputPortWithVideoStatuses VgaIn { get; private set; }
public RoutingInputPortWithVideoStatuses CompositeIn { get; private set; }
public RoutingOutputPort DmOut { get; private set; }
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
public BoolFeedback HdmiVideoSyncFeedback { get; protected set; }
public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
@@ -54,88 +54,88 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary>
/// Helps get the "real" inputs, including when in Auto
/// </summary>
public BaseDmTx401.eSourceSelection ActualVideoInput
{
get
{
if (Tx.VideoSourceFeedback != BaseDmTx401.eSourceSelection.Auto)
return Tx.VideoSourceFeedback;
else // auto
{
if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.HDMI;
else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.VGA;
else if (Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.DisplayPort;
else if (Tx.CvbsInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.Composite;
else
return BaseDmTx401.eSourceSelection.Disabled;
}
}
}
public RoutingPortCollection<RoutingInputPort> InputPorts
{
get
{
return new RoutingPortCollection<RoutingInputPort>
{
HdmiIn,
DisplayPortIn,
VgaIn,
CompositeIn,
AnyVideoInput
};
}
}
public RoutingPortCollection<RoutingOutputPort> OutputPorts
{
get
{
return new RoutingPortCollection<RoutingOutputPort> { DmOut };
}
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="tx"></param>
public DmTx401CController(string key, string name, DmTx401C tx)
: base(key, name, tx)
{
Tx = tx;
HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this,
}
/// <summary>
/// Helps get the "real" inputs, including when in Auto
/// </summary>
public BaseDmTx401.eSourceSelection ActualVideoInput
{
get
{
if (Tx.VideoSourceFeedback != BaseDmTx401.eSourceSelection.Auto)
return Tx.VideoSourceFeedback;
else // auto
{
if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.HDMI;
else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.VGA;
else if (Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.DisplayPort;
else if (Tx.CvbsInput.SyncDetectedFeedback.BoolValue)
return BaseDmTx401.eSourceSelection.Composite;
else
return BaseDmTx401.eSourceSelection.Disabled;
}
}
}
public RoutingPortCollection<RoutingInputPort> InputPorts
{
get
{
return new RoutingPortCollection<RoutingInputPort>
{
HdmiIn,
DisplayPortIn,
VgaIn,
CompositeIn,
AnyVideoInput
};
}
}
public RoutingPortCollection<RoutingOutputPort> OutputPorts
{
get
{
return new RoutingPortCollection<RoutingOutputPort> { DmOut };
}
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="tx"></param>
public DmTx401CController(string key, string name, DmTx401C tx)
: base(key, name, tx)
{
Tx = tx;
HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput))
{
FeedbackMatchObject = eVst.HDMI
};
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.DisplayPort, this,
};
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.DisplayPort, this,
VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput))
{
FeedbackMatchObject = eVst.DisplayPort
};
VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.VGA, this,
};
VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.VGA, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = eVst.VGA
};
CompositeIn = new RoutingInputPortWithVideoStatuses(DmPortName.CompositeIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Composite, eVst.Composite, this,
};
CompositeIn = new RoutingInputPortWithVideoStatuses(DmPortName.CompositeIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Composite, eVst.Composite, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = eVst.Composite
@@ -146,184 +146,185 @@ namespace PepperDash.Essentials.DM
Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualVideoInput.ToString());
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () => tx.HdmiInput.HdcpSupportOnFeedback.BoolValue ? 1 : 0);
HdcpStateFeedback = HdmiInHdcpCapabilityFeedback;
HdcpStateFeedback = HdmiInHdcpCapabilityFeedback;
HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
DisplayPortVideoSyncFeedback = new BoolFeedback("DisplayPortVideoSync", () => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue);
HdmiVideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInput.SyncDetectedFeedback.BoolValue);
VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue);
FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
(ActualVideoInput == eVst.HDMI
&& tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue)
|| (ActualVideoInput == eVst.DisplayPort
&& tx.DisplayPortInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
HdcpStateFeedbackFunc = () =>
{
if (ActualVideoInput == eVst.HDMI)
return tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString();
if (ActualVideoInput == eVst.DisplayPort)
return tx.DisplayPortInput.VideoAttributes.HdcpStateFeedback.ToString();
return "";
},
VideoResolutionFeedbackFunc = () =>
{
if (ActualVideoInput == eVst.HDMI)
return tx.HdmiInput.VideoAttributes.GetVideoResolutionString();
if (ActualVideoInput == eVst.DisplayPort)
return tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString();
if (ActualVideoInput == eVst.VGA)
return tx.VgaInput.VideoAttributes.GetVideoResolutionString();
if (ActualVideoInput == eVst.Composite)
return tx.CvbsInput.VideoAttributes.GetVideoResolutionString();
return "";
},
VideoSyncFeedbackFunc = () =>
(ActualVideoInput == eVst.HDMI
&& tx.HdmiInput.SyncDetectedFeedback.BoolValue)
|| (ActualVideoInput == eVst.DisplayPort
&& tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
|| (ActualVideoInput == eVst.VGA
&& tx.VgaInput.SyncDetectedFeedback.BoolValue)
|| (ActualVideoInput == eVst.Composite
&& tx.CvbsInput.SyncDetectedFeedback.BoolValue)
};
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.DmCat, null, this);
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, DisplayPortVideoSyncFeedback,
HdmiVideoSyncFeedback, VgaVideoSyncFeedback);
// Set Ports for CEC
DisplayPortIn.Port = Tx.DisplayPortInput;
HdmiIn.Port = Tx.HdmiInput;
DmOut.Port = Tx.DmOutput;
}
public override bool CustomActivate()
{
// Link up all of these damned events to the various RoutingPorts via a helper handler
Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn, a.EventId);
Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn, a.EventId);
Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId);
Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId);
Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaIn, a.EventId);
Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(VgaIn, a.EventId);
// Base does register and sets up comm monitoring.
return base.CustomActivate();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
if (HdmiVideoSyncFeedback != null)
VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue);
FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
(ActualVideoInput == eVst.HDMI
&& tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue)
|| (ActualVideoInput == eVst.DisplayPort
&& tx.DisplayPortInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
HdcpStateFeedbackFunc = () =>
{
if (ActualVideoInput == eVst.HDMI)
return tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString();
if (ActualVideoInput == eVst.DisplayPort)
return tx.DisplayPortInput.VideoAttributes.HdcpStateFeedback.ToString();
return "";
},
VideoResolutionFeedbackFunc = () =>
{
if (ActualVideoInput == eVst.HDMI)
return tx.HdmiInput.VideoAttributes.GetVideoResolutionString();
if (ActualVideoInput == eVst.DisplayPort)
return tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString();
if (ActualVideoInput == eVst.VGA)
return tx.VgaInput.VideoAttributes.GetVideoResolutionString();
if (ActualVideoInput == eVst.Composite)
return tx.CvbsInput.VideoAttributes.GetVideoResolutionString();
return "";
},
VideoSyncFeedbackFunc = () =>
(ActualVideoInput == eVst.HDMI
&& tx.HdmiInput.SyncDetectedFeedback.BoolValue)
|| (ActualVideoInput == eVst.DisplayPort
&& tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
|| (ActualVideoInput == eVst.VGA
&& tx.VgaInput.SyncDetectedFeedback.BoolValue)
|| (ActualVideoInput == eVst.Composite
&& tx.CvbsInput.SyncDetectedFeedback.BoolValue)
};
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.DmCat, null, this);
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, DisplayPortVideoSyncFeedback,
HdmiVideoSyncFeedback, VgaVideoSyncFeedback);
// Set Ports for CEC
DisplayPortIn.Port = Tx.DisplayPortInput;
HdmiIn.Port = Tx.HdmiInput;
DmOut.Port = Tx.DmOutput;
}
public override bool CustomActivate()
{
// Link up all of these damned events to the various RoutingPorts via a helper handler
Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn, a.EventId);
Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn, a.EventId);
Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId);
Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, a.EventId);
Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaIn, a.EventId);
Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(VgaIn, a.EventId);
// Base does register and sets up comm monitoring.
return base.CustomActivate();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
if (HdmiVideoSyncFeedback != null)
{
HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
}
if (VgaVideoSyncFeedback != null)
{
HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
}
if (VgaVideoSyncFeedback != null)
{
VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
}
LinkDmTxToApi(this, trilist, joinMap, bridge);
}
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
switch (input)
{
case 0:
{
ExecuteSwitch(eVst.Auto, null, type);
break;
}
case 1:
{
ExecuteSwitch(DisplayPortIn.Selector, null, type);
break;
}
case 2:
{
ExecuteSwitch(HdmiIn.Selector, null, type);
break;
}
case 3:
{
ExecuteSwitch(VgaIn.Selector, null, type);
break;
}
case 4:
{
ExecuteSwitch(CompositeIn.Selector, null, type);
break;
}
case 5:
{
ExecuteSwitch(eVst.Disabled, null, type);
break;
}
}
}
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
Tx.VideoSource = (eVst)inputSelector;
if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
Tx.AudioSource = (eVst)inputSelector;
VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
}
LinkDmTxToApi(this, trilist, joinMap, bridge);
}
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
switch (input)
{
case 0:
{
ExecuteSwitch(eVst.Auto, null, type);
break;
}
case 1:
{
ExecuteSwitch(DisplayPortIn.Selector, null, type);
break;
}
case 2:
{
ExecuteSwitch(HdmiIn.Selector, null, type);
break;
}
case 3:
{
ExecuteSwitch(VgaIn.Selector, null, type);
break;
}
case 4:
{
ExecuteSwitch(CompositeIn.Selector, null, type);
break;
}
case 5:
{
ExecuteSwitch(eVst.Disabled, null, type);
break;
}
}
}
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
Tx.VideoSource = (eVst)inputSelector;
if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
Tx.AudioSource = (eVst)inputSelector;
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
}
void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
@@ -347,7 +348,7 @@ namespace PepperDash.Essentials.DM
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
}
}
void VideoControls_ControlChange(object sender, GenericEventArgs args)
{
@@ -363,7 +364,7 @@ namespace PepperDash.Essentials.DM
VgaContrastFeedback.FireUpdate();
break;
}
}
}
/// <summary>
/// Enables or disables free run
@@ -390,10 +391,10 @@ namespace PepperDash.Essentials.DM
public void SetVgaContrast(ushort level)
{
Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
}
/// <summary>
/// Relays the input stream change to the appropriate RoutingInputPort.
}
/// <summary>
/// Relays the input stream change to the appropriate RoutingInputPort.
/// </summary>
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
@@ -403,36 +404,36 @@ namespace PepperDash.Essentials.DM
}
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
}
/// <summary>
/// Relays the VideoAttributes change to a RoutingInputPort
/// </summary>
void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
//// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
//Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
// args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
switch (eventId)
{
case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HdcpStateFeedbackEventId:
inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
}
}
/// <summary>
/// Relays the VideoAttributes change to a RoutingInputPort
/// </summary>
void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
//// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
//Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
// args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
switch (eventId)
{
case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HdcpStateFeedbackEventId:
inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
}
}
void HdmiInputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
@@ -476,18 +477,18 @@ namespace PepperDash.Essentials.DM
VgaVideoSyncFeedback.FireUpdate();
break;
}
}
#region IIROutputPorts Members
public CrestronCollection<IROutputPort> IROutputPorts { get { return Tx.IROutputPorts; } }
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
#endregion
#region IComPorts Members
public CrestronCollection<ComPort> ComPorts { get { return Tx.ComPorts; } }
public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
#endregion
}
}
#region IIROutputPorts Members
public CrestronCollection<IROutputPort> IROutputPorts { get { return Tx.IROutputPorts; } }
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
#endregion
#region IComPorts Members
public CrestronCollection<ComPort> ComPorts { get { return Tx.ComPorts; } }
public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
#endregion
}
}

View File

@@ -149,7 +149,7 @@ namespace PepperDash.Essentials.Devices.Displays
public override bool CustomActivate()
{
Communication.Connect();
CommunicationMonitor.StatusChange += (o, a) => Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status);
CommunicationMonitor.StatusChange += (o, a) => { Debug.Console(2, this, "Communication monitor state: {0}", CommunicationMonitor.Status); };
CommunicationMonitor.Start();
return true;
}
@@ -188,6 +188,9 @@ namespace PepperDash.Essentials.Devices.Displays
IncomingBuffer.CopyTo(newBytes, 0);
e.Bytes.CopyTo(newBytes, IncomingBuffer.Length);
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
Debug.Console(2, this, "Received:{0}", ComTextHelper.GetEscapedText(newBytes));
// Need to find AA FF and have
for (int i = 0; i < newBytes.Length; i++)
{
@@ -361,6 +364,8 @@ namespace PepperDash.Essentials.Devices.Displays
}
checksum = checksum & 0x000000FF; // mask off MSBs
b[b.Length - 1] = (byte)checksum;
if(Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
Debug.Console(2, this, "Sending:{0}", ComTextHelper.GetEscapedText(b));
if (b[1] == 0x12)
LastCommandSentWasVolume = true;

View File

@@ -12,12 +12,11 @@ using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Core.Routing;
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
namespace PepperDash.Essentials.Devices.Common
{
[Description("Wrapper class for an IR Set Top Box")]
public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IHasPowerControl, ITvPresetsProvider
public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IHasPowerControl
{
public IrOutputPortController IrPort { get; private set; }
@@ -29,7 +28,7 @@ namespace PepperDash.Essentials.Devices.Common
public bool HasDpad { get; set; }
public bool HasNumeric { get; set; }
public DevicePresetsModel TvPresets { get; private set; }
public DevicePresetsModel PresetsModel { get; private set; }
public IRSetTopBoxBase(string key, string name, IrOutputPortController portCont,
SetTopBoxPropertiesConfig props)
@@ -67,8 +66,8 @@ namespace PepperDash.Essentials.Devices.Common
public void LoadPresets(string filePath)
{
TvPresets = new DevicePresetsModel(Key + "-presets", this, filePath);
DeviceManager.AddDevice(TvPresets);
PresetsModel = new DevicePresetsModel(Key + "-presets", this, filePath);
DeviceManager.AddDevice(PresetsModel);
}

View File

@@ -1369,7 +1369,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
set
{
// If the incoming value is "On" it sets the BoolValue true, otherwise sets it false
BoolValue = value == "On" || value == "Standby";
BoolValue = value == "On";
OnValueChanged();
}
}