mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-27 19:34:51 +00:00
Compare commits
98 Commits
1.5.3-beta
...
1.5.7-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8a8d481aa | ||
|
|
fd1de75a1d | ||
|
|
7f08bfc913 | ||
|
|
6f16bc3427 | ||
|
|
35ec5e903e | ||
|
|
f98292a4aa | ||
|
|
6b6604b7a9 | ||
|
|
55eb110373 | ||
|
|
42418fedb8 | ||
|
|
407fc2e948 | ||
|
|
49177da820 | ||
|
|
a1809dccb4 | ||
|
|
7d97bc118e | ||
|
|
48bc41a69e | ||
|
|
e4a8e89135 | ||
|
|
1bd6825258 | ||
|
|
e5099e9a2a | ||
|
|
ccdaa12f20 | ||
|
|
60d387c792 | ||
|
|
d9b4ca815e | ||
|
|
37686044d4 | ||
|
|
ef50098460 | ||
|
|
f2eff3fdb4 | ||
|
|
2749fdc2e9 | ||
|
|
514fe466fd | ||
|
|
c77d394e08 | ||
|
|
b689a54936 | ||
|
|
1046672386 | ||
|
|
0cfcf4f266 | ||
|
|
d86cc44c3b | ||
|
|
26bd0d624e | ||
|
|
841cb2a83b | ||
|
|
b89112bec1 | ||
|
|
5920c7c0f0 | ||
|
|
d23ef01281 | ||
|
|
dab153f1b0 | ||
|
|
c5ad321842 | ||
|
|
c78b305faa | ||
|
|
5853dd6617 | ||
|
|
a67b435565 | ||
|
|
84d8ff410e | ||
|
|
625c870072 | ||
|
|
c475155546 | ||
|
|
1b6669d4ef | ||
|
|
ffbba24b5a | ||
|
|
9bdbb1fbad | ||
|
|
0465a3b9a6 | ||
|
|
a0ef356bac | ||
|
|
e62dd762f4 | ||
|
|
9c4e4c7976 | ||
|
|
486d6db7d8 | ||
|
|
81d9261a73 | ||
|
|
2ace6ef6bc | ||
|
|
cc6d94b188 | ||
|
|
0525f76b6b | ||
|
|
7fa3031cfa | ||
|
|
d34177482e | ||
|
|
345442e195 | ||
|
|
e94e8b60a6 | ||
|
|
4f4c8cba04 | ||
|
|
1be0a3cba9 | ||
|
|
ce513ac086 | ||
|
|
c98cd05a5c | ||
|
|
d68645ccb0 | ||
|
|
9517eaa0b0 | ||
|
|
6b140bf2d7 | ||
|
|
eab0d2b1d7 | ||
|
|
df8a885594 | ||
|
|
5ea79ac94e | ||
|
|
459dc951e9 | ||
|
|
f823abacc1 | ||
|
|
0a38442ac5 | ||
|
|
083a3662e0 | ||
|
|
37e1e50b94 | ||
|
|
f0eeae0432 | ||
|
|
4b663eea62 | ||
|
|
8d2d45b5ce | ||
|
|
62fdd6a572 | ||
|
|
305fe5c372 | ||
|
|
b39afe2f50 | ||
|
|
862610b17d | ||
|
|
43698ba839 | ||
|
|
7bfc82c3cc | ||
|
|
b975ce6a6d | ||
|
|
e83acd5bfa | ||
|
|
2f1592bc62 | ||
|
|
1c609764b8 | ||
|
|
c7464a1e34 | ||
|
|
608a9068b9 | ||
|
|
e006a4616a | ||
|
|
677789bec1 | ||
|
|
0dc589f2ea | ||
|
|
aecb36e937 | ||
|
|
be97fe15da | ||
|
|
2a7311ba50 | ||
|
|
b95c341fca | ||
|
|
ef4b0441d3 | ||
|
|
f81fe3d01f |
4
.github/scripts/GenerateVersionNumber.ps1
vendored
4
.github/scripts/GenerateVersionNumber.ps1
vendored
@@ -1,4 +1,4 @@
|
||||
$latestVersions = $(git tag --merged origin/master)
|
||||
$latestVersions = $(git tag --merged origin/main)
|
||||
$latestVersion = [version]"0.0.0"
|
||||
Foreach ($version in $latestVersions) {
|
||||
Write-Host $version
|
||||
@@ -18,7 +18,7 @@ $newVersion = [version]$latestVersion
|
||||
$phase = ""
|
||||
$newVersionString = ""
|
||||
switch -regex ($Env:GITHUB_REF) {
|
||||
'^refs\/heads\/master*.' {
|
||||
'^refs\/heads\/main*.' {
|
||||
$newVersionString = "{0}.{1}.{2}" -f $newVersion.Major, $newVersion.Minor, $newVersion.Build
|
||||
}
|
||||
'^refs\/heads\/feature\/*.' {
|
||||
|
||||
8
.github/workflows/docker.yml
vendored
8
.github/workflows/docker.yml
vendored
@@ -18,8 +18,8 @@ env:
|
||||
VERSION: 0.0.0-buildtype-buildnumber
|
||||
# Defaults to debug for build type
|
||||
BUILD_TYPE: Debug
|
||||
# Defaults to master as the release branch. Change as necessary
|
||||
RELEASE_BRANCH: master
|
||||
# Defaults to main as the release branch. Change as necessary
|
||||
RELEASE_BRANCH: main
|
||||
jobs:
|
||||
Build_Project:
|
||||
runs-on: windows-latest
|
||||
@@ -189,11 +189,11 @@ jobs:
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
# This step only runs if the branch is master or release/ runs and pushes the build to the public build repo
|
||||
# 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, 'master') || contains(github.ref, '/release/')
|
||||
if: contains(github.ref, 'main') || contains(github.ref, '/release/')
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: check Github ref
|
||||
|
||||
22
.github/workflows/master.yml
vendored
22
.github/workflows/master.yml
vendored
@@ -1,11 +1,11 @@
|
||||
name: Master Build using Docker
|
||||
name: main Build using Docker
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
env:
|
||||
# solution path doesn't need slashes unless there it is multiple folders deep
|
||||
# solution name does not include extension. .sln is assumed
|
||||
@@ -15,8 +15,8 @@ env:
|
||||
VERSION: 0.0.0-buildtype-buildnumber
|
||||
# Defaults to debug for build type
|
||||
BUILD_TYPE: Release
|
||||
# Defaults to master as the release branch. Change as necessary
|
||||
RELEASE_BRANCH: master
|
||||
# Defaults to main as the release branch. Change as necessary
|
||||
RELEASE_BRANCH: main
|
||||
jobs:
|
||||
Build_Project:
|
||||
runs-on: windows-latest
|
||||
@@ -114,8 +114,8 @@ jobs:
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Checkout Master branch
|
||||
run: git checkout master
|
||||
- name: Checkout main branch
|
||||
run: git checkout main
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
@@ -151,13 +151,13 @@ jobs:
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin master --force
|
||||
run: git push -u origin main --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
# This step only runs if the branch is master or release/ runs and pushes the build to the public build repo
|
||||
# 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
|
||||
@@ -186,9 +186,9 @@ jobs:
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout master branch
|
||||
# Checkout main branch
|
||||
- name: Create new branch
|
||||
run: git checkout master
|
||||
run: git checkout main
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
@@ -224,7 +224,7 @@ jobs:
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin master --force
|
||||
run: git push -u origin main --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Bridges;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
@@ -15,15 +15,11 @@ namespace PepperDash.Essentials.Bridges
|
||||
{
|
||||
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
protected Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
|
||||
|
||||
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
|
||||
|
||||
public EiscApi(DeviceConfig dc) :
|
||||
base(dc.Key)
|
||||
{
|
||||
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
|
||||
|
||||
PropertiesConfig = dc.Properties.ToObject<EiscApiPropertiesConfig>();
|
||||
//PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
@@ -44,19 +40,31 @@ namespace PepperDash.Essentials.Bridges
|
||||
if (device == null) continue;
|
||||
|
||||
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||
if (device is IBridge) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type.
|
||||
if (typeof(IBridge).IsAssignableFrom(device.GetType().GetCType())) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type.
|
||||
{
|
||||
Debug.Console(2, this, "'{0}' is IBridge", device.Key);
|
||||
|
||||
var dev = device as IBridge;
|
||||
|
||||
if (dev == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Cast to IBridge failed for {0}");
|
||||
continue;
|
||||
}
|
||||
|
||||
dev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey);
|
||||
}
|
||||
if (!(device is IBridgeAdvanced)) continue;
|
||||
if (!typeof(IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType())) continue;
|
||||
Debug.Console(2, this, "'{0}' is IBridgeAdvanced", device.Key);
|
||||
|
||||
var advDev = device as IBridgeAdvanced;
|
||||
|
||||
if (advDev == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Cast to IBridgeAdvanced failed for {0}");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
advDev.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, null);
|
||||
@@ -66,63 +74,12 @@ namespace PepperDash.Essentials.Bridges
|
||||
Debug.ConsoleWithLog(0, this,
|
||||
"Please update the bridge config to use EiscBridgeAdvanced with this device: {0}", device.Key);
|
||||
}
|
||||
|
||||
}
|
||||
Debug.Console(1, this, "Devices Linked.");
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a join map
|
||||
/// </summary>
|
||||
/// <param name="deviceKey"></param>
|
||||
/// <param name="joinMap"></param>
|
||||
public void AddJoinMap(string deviceKey, JoinMapBaseAdvanced joinMap)
|
||||
{
|
||||
if (!JoinMaps.ContainsKey(deviceKey))
|
||||
{
|
||||
JoinMaps.Add(deviceKey, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, this, "Unable to add join map with key '{0}'. Key already exists in JoinMaps dictionary", deviceKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints all the join maps on this bridge
|
||||
/// </summary>
|
||||
public void PrintJoinMaps()
|
||||
{
|
||||
Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X"));
|
||||
|
||||
foreach (var joinMap in JoinMaps)
|
||||
{
|
||||
Debug.Console(0, "Join map for device '{0}':", joinMap.Key);
|
||||
joinMap.Value.PrintJoinMapInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints the join map for a device by key
|
||||
/// </summary>
|
||||
/// <param name="deviceKey"></param>
|
||||
public void PrintJoinMapForDevice(string deviceKey)
|
||||
{
|
||||
var joinMap = JoinMaps[deviceKey];
|
||||
|
||||
if (joinMap == null)
|
||||
{
|
||||
Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
|
||||
joinMap.PrintJoinMapInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for debugging to trigger an action based on a join number and type
|
||||
/// </summary>
|
||||
@@ -194,7 +151,7 @@ namespace PepperDash.Essentials.Bridges
|
||||
try
|
||||
{
|
||||
if (Debug.Level >= 1)
|
||||
Debug.Console(1, this, "EiscApiAdvanced change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
Debug.Console(1, this, "EiscApi change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
var uo = args.Sig.UserObject;
|
||||
|
||||
if (uo == null) return;
|
||||
|
||||
@@ -555,7 +555,7 @@ namespace PepperDash.Essentials
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route, SourceListItem sourceItem, string sourceItemKey)
|
||||
{
|
||||
IRoutingSinkNoSwitching dest = null;
|
||||
IRoutingSink dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace PepperDash.Essentials
|
||||
public EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||
public IRoutingSink DefaultAudioDevice { get; private set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
@@ -471,14 +471,14 @@ namespace PepperDash.Essentials
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSinkNoSwitching dest = null;
|
||||
IRoutingSink dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice;
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultDisplay;
|
||||
else
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink;
|
||||
|
||||
if (dest == null)
|
||||
{
|
||||
|
||||
@@ -590,7 +590,7 @@ namespace PepperDash.Essentials
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSinkNoSwitching dest = null;
|
||||
IRoutingSink dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
# PepperDash Essentials Framework (c) 2020
|
||||
|
||||
## [Latest Release](https://github.com/PepperDash/Essentials/releases/latest)
|
||||
|
||||
## License
|
||||
Provided under MIT license
|
||||
|
||||
@@ -10,7 +12,7 @@ PepperDash Essentials is an open source Crestron framework that can be configure
|
||||
Essentials Framework is a collection of C# / Simpl# Pro libraries that can be utilized in several different manners. It is currently operating as a 100% configuration-driven system, and can be extended to add different workflows and behaviors, either through the addition of further device "types" or via the plug-in mechanism. The framework is a collection of "things" that are all related and interconnected, but in general do not have dependencies on each other.
|
||||
|
||||
## Minimum Requirements
|
||||
- Essentials Framework runs on any Crestron 3-series processor or Crestron's VC-4 platform.
|
||||
- Essentials Framework runs on any Crestron 3-series processor, **4-series** processor or Crestron's VC-4 platform.
|
||||
- To edit and compile the source, Microsoft Visual Studio 2008 Professional with SP1 is required.
|
||||
- Crestron's Simpl# Plugin is also required (must be obtained from Crestron).
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ using Crestron.SimplSharpPro.EthernetCommunication;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
//using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
@@ -110,20 +109,18 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
if (device == null) continue;
|
||||
|
||||
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||
//if (device is IBridge) // Check for this first to allow bridges in plugins to override existing bridges that apply to the same type.
|
||||
//{
|
||||
// Debug.Console(2, this, "'{0}' is IBridge", device.Key);
|
||||
//}
|
||||
|
||||
if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
|
||||
device.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
var bridge = device as IBridgeAdvanced;
|
||||
if (bridge != null) bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -294,7 +291,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public EiscApiAdvancedFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "eiscapiadv", "eiscapiadvanced" };
|
||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
|
||||
@@ -89,6 +89,43 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public JoinDataComplete OutputNames = new JoinDataComplete(new JoinData() { JoinNumber = 301, JoinSpan = 32 },
|
||||
new JoinMetadata() { Label = "DM Chassis Output Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("InputVideoNames")] public JoinDataComplete InputVideoNames =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 501, JoinSpan = 200},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Video Input Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("InputAudioNames")]
|
||||
public JoinDataComplete InputAudioNames =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 701, JoinSpan = 200 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Video Input Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
[JoinName("OutputVideoNames")]
|
||||
public JoinDataComplete OutputVideoNames =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 901, JoinSpan = 200 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Video Input Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
[JoinName("OutputAudioNames")]
|
||||
public JoinDataComplete OutputAudioNames =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 1101, JoinSpan = 200 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Video Input Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("OutputCurrentVideoInputNames")]
|
||||
public JoinDataComplete OutputCurrentVideoInputNames = new JoinDataComplete(new JoinData() { JoinNumber = 2001, JoinSpan = 32 },
|
||||
new JoinMetadata() { Label = "DM Chassis Video Output Currently Routed Video Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
@@ -17,10 +17,6 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public JoinDataComplete EnableAutoRoute = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata() { Label = "Enable Automatic Routing on 4x1 Switchers", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("DisableAutoRoute")]
|
||||
public JoinDataComplete DisableAutoRoute = new JoinDataComplete(new JoinData() { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata() { Label = "Disable Automatic Routing on 4x1 Switchers", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("InputName")]
|
||||
public JoinDataComplete InputName = new JoinDataComplete(new JoinData() { JoinNumber = 2, JoinSpan = 8 },
|
||||
new JoinMetadata() { Label = "Device Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
@@ -11,8 +11,10 @@ using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class ComPortController : Device, IBasicCommunication
|
||||
public class ComPortController : Device, IBasicCommunicationWithStreamDebugging
|
||||
{
|
||||
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
||||
|
||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||
|
||||
@@ -24,6 +26,8 @@ namespace PepperDash.Essentials.Core
|
||||
public ComPortController(string key, Func<EssentialsControlPropertiesConfig, ComPort> postActivationFunc,
|
||||
ComPort.ComPortSpec spec, EssentialsControlPropertiesConfig config) : base(key)
|
||||
{
|
||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||
|
||||
Spec = spec;
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
@@ -91,7 +95,12 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
var textHandler = TextReceived;
|
||||
if (textHandler != null)
|
||||
{
|
||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Recevied: '{0}'", s);
|
||||
|
||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Deactivate()
|
||||
@@ -105,7 +114,10 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
if (Port == null)
|
||||
return;
|
||||
Port.Send(text);
|
||||
|
||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text);
|
||||
Port.Send(text);
|
||||
}
|
||||
|
||||
public void SendBytes(byte[] bytes)
|
||||
@@ -113,6 +125,9 @@ namespace PepperDash.Essentials.Core
|
||||
if (Port == null)
|
||||
return;
|
||||
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
||||
|
||||
Port.Send(text);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,14 @@ namespace PepperDash.Essentials.Core
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IBasicCommunicationJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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.");
|
||||
}
|
||||
|
||||
if (CommPort == null)
|
||||
{
|
||||
@@ -96,7 +103,7 @@ namespace PepperDash.Essentials.Core
|
||||
trilist.SetStringSigAction(joinMap.SetPortConfig.JoinNumber, SetPortConfig);
|
||||
|
||||
|
||||
var sComm = this as ISocketStatus;
|
||||
var sComm = CommPort as ISocketStatus;
|
||||
if (sComm == null) return;
|
||||
sComm.ConnectionChange += (s, a) =>
|
||||
{
|
||||
@@ -55,7 +55,14 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<C2nRthsControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Crestron.SimplSharpProInternal;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
public class C3CardControllerBase:CrestronGenericBaseDevice
|
||||
{
|
||||
private readonly C3Card _card;
|
||||
|
||||
public C3CardControllerBase(string key, string name, C3Card hardware) : base(key, name, hardware)
|
||||
{
|
||||
_card = hardware;
|
||||
}
|
||||
|
||||
#region Overrides of Object
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0} {1}", Key, _card.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
public class C3Com3Controller:C3CardControllerBase, IComPorts
|
||||
{
|
||||
private readonly C3com3 _card;
|
||||
|
||||
public C3Com3Controller(string key, string name, C3com3 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_card = hardware;
|
||||
}
|
||||
|
||||
#region Implementation of IComPorts
|
||||
|
||||
public CrestronCollection<ComPort> ComPorts
|
||||
{
|
||||
get { return _card.ComPorts; }
|
||||
}
|
||||
|
||||
public int NumberOfComPorts
|
||||
{
|
||||
get { return _card.NumberOfComPorts; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
public class C3Io16Controller:C3CardControllerBase,IIOPorts
|
||||
{
|
||||
private readonly C3io16 _card;
|
||||
|
||||
public C3Io16Controller(string key, string name, C3io16 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_card = hardware;
|
||||
}
|
||||
|
||||
#region Implementation of IIOPorts
|
||||
|
||||
public CrestronCollection<Versiport> VersiPorts
|
||||
{
|
||||
get { return _card.VersiPorts; }
|
||||
}
|
||||
|
||||
public int NumberOfVersiPorts
|
||||
{
|
||||
get { return _card.NumberOfVersiPorts; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
public class C3Ir8Controller:C3CardControllerBase, IIROutputPorts
|
||||
{
|
||||
private readonly C3ir8 _card;
|
||||
|
||||
public C3Ir8Controller(string key, string name, C3ir8 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_card = hardware;
|
||||
}
|
||||
|
||||
#region Implementation of IIROutputPorts
|
||||
|
||||
public CrestronCollection<IROutputPort> IROutputPorts
|
||||
{
|
||||
get { return _card.IROutputPorts; }
|
||||
}
|
||||
|
||||
public int NumberOfIROutputPorts
|
||||
{
|
||||
get { return _card.NumberOfIROutputPorts; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
public class C3Ry16Controller:C3CardControllerBase, IRelayPorts
|
||||
{
|
||||
private readonly C3ry16 _card;
|
||||
|
||||
public C3Ry16Controller(string key, string name, C3ry16 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_card = hardware;
|
||||
}
|
||||
|
||||
#region Implementation of IRelayPorts
|
||||
|
||||
public CrestronCollection<Relay> RelayPorts
|
||||
{
|
||||
get { return _card.RelayPorts; }
|
||||
}
|
||||
|
||||
public int NumberOfRelayPorts
|
||||
{
|
||||
get { return _card.NumberOfRelayPorts; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
public class C3Ry8Controller:C3CardControllerBase, IRelayPorts
|
||||
{
|
||||
private readonly C3ry8 _card;
|
||||
|
||||
public C3Ry8Controller(string key, string name, C3ry8 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_card = hardware;
|
||||
}
|
||||
|
||||
#region Implementation of IRelayPorts
|
||||
|
||||
public CrestronCollection<Relay> RelayPorts
|
||||
{
|
||||
get { return _card.RelayPorts; }
|
||||
}
|
||||
|
||||
public int NumberOfRelayPorts
|
||||
{
|
||||
get { return _card.NumberOfRelayPorts; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
[ConfigSnippet("\"properties\":{\"card\":\"c3com3\"}")]
|
||||
public class CenCi31Controller : CrestronGenericBaseDevice
|
||||
{
|
||||
private const string CardKeyTemplate = "{0}-card";
|
||||
private const string CardNameTemplate = "{0}:{1}:{2}";
|
||||
private const uint CardSlot = 1;
|
||||
private readonly CenCi31 _cardCage;
|
||||
private readonly CenCi31Configuration _config;
|
||||
|
||||
private readonly Dictionary<string, Func<CenCi31, uint, C3CardControllerBase>> _cardDict;
|
||||
|
||||
public CenCi31Controller(string key, string name, CenCi31Configuration config, CenCi31 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_cardCage = hardware;
|
||||
|
||||
_config = config;
|
||||
|
||||
_cardDict = new Dictionary<string, Func<CenCi31, uint, C3CardControllerBase>>
|
||||
{
|
||||
{
|
||||
"c3com3",
|
||||
(c, s) =>
|
||||
new C3Com3Controller(String.Format(CardKeyTemplate, key),
|
||||
String.Format(CardNameTemplate, key, s, "C3Com3"), new C3com3(_cardCage))
|
||||
},
|
||||
{
|
||||
"c3io16",
|
||||
(c, s) =>
|
||||
new C3Io16Controller(String.Format(CardKeyTemplate, key),
|
||||
String.Format(CardNameTemplate, key, s,"C3Io16"), new C3io16(_cardCage))
|
||||
},
|
||||
{
|
||||
"c3ir8",
|
||||
(c, s) =>
|
||||
new C3Ir8Controller(String.Format(CardKeyTemplate, key),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ir8"), new C3ir8(_cardCage))
|
||||
},
|
||||
{
|
||||
"c3ry16",
|
||||
(c, s) =>
|
||||
new C3Ry16Controller(String.Format(CardKeyTemplate, key),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ry16"), new C3ry16(_cardCage))
|
||||
},
|
||||
{
|
||||
"c3ry8",
|
||||
(c, s) =>
|
||||
new C3Ry8Controller(String.Format(CardKeyTemplate, key),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ry8"), new C3ry8(_cardCage))
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
GetCards();
|
||||
}
|
||||
|
||||
private void GetCards()
|
||||
{
|
||||
Func<CenCi31, uint, C3CardControllerBase> cardBuilder;
|
||||
|
||||
if (String.IsNullOrEmpty(_config.Card))
|
||||
{
|
||||
Debug.Console(0, this, "No card specified");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_cardDict.TryGetValue(_config.Card.ToLower(), out cardBuilder))
|
||||
{
|
||||
Debug.Console(0, "Unable to find factory for 3-Series card type {0}.", _config.Card);
|
||||
return;
|
||||
}
|
||||
|
||||
var device = cardBuilder(_cardCage, CardSlot);
|
||||
|
||||
DeviceManager.AddDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
public class CenCi31Configuration
|
||||
{
|
||||
[JsonProperty("card")]
|
||||
public string Card { get; set; }
|
||||
}
|
||||
|
||||
public class CenCi31ControllerFactory : EssentialsDeviceFactory<CenCi31Controller>
|
||||
{
|
||||
public CenCi31ControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string> {"cenci31"};
|
||||
}
|
||||
#region Overrides of EssentialsDeviceFactory<CenCi31Controller>
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory attempting to build new CEN-CI-1");
|
||||
|
||||
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var ipId = controlProperties.IpIdInt;
|
||||
|
||||
var cardCage = new CenCi31(ipId, Global.ControlSystem);
|
||||
var config = dc.Properties.ToObject<CenCi31Configuration>();
|
||||
|
||||
return new CenCi31Controller(dc.Key, dc.Name, config, cardCage);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
[ConfigSnippet("\"properties\":{\"cards\":{\"1\":\"c3com3\",\"2\":\"c3ry16\",\"3\":\"c3ry8\"}}")]
|
||||
public class CenCi33Controller : CrestronGenericBaseDevice
|
||||
{
|
||||
private const string CardKeyTemplate = "{0}-card{1}";
|
||||
private const string CardNameTemplate = "{0}:{1}:{2}";
|
||||
private const uint CardSlots = 3;
|
||||
private readonly CenCi33 _cardCage;
|
||||
private readonly CenCi33Configuration _config;
|
||||
|
||||
private readonly Dictionary<string, Func<CenCi33, uint, C3CardControllerBase>> _cardDict;
|
||||
|
||||
public CenCi33Controller(string key, string name, CenCi33Configuration config, CenCi33 hardware) : base(key, name, hardware)
|
||||
{
|
||||
_cardCage = hardware;
|
||||
|
||||
_config = config;
|
||||
|
||||
_cardDict = new Dictionary<string, Func<CenCi33, uint, C3CardControllerBase>>
|
||||
{
|
||||
{
|
||||
"c3com3",
|
||||
(c, s) =>
|
||||
new C3Com3Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Com3"), new C3com3(s,_cardCage))
|
||||
},
|
||||
{
|
||||
"c3io16",
|
||||
(c, s) =>
|
||||
new C3Io16Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Io16"), new C3io16(s,_cardCage))
|
||||
},
|
||||
{
|
||||
"c3ir8",
|
||||
(c, s) =>
|
||||
new C3Ir8Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ir8"), new C3ir8(s,_cardCage))
|
||||
},
|
||||
{
|
||||
"c3ry16",
|
||||
(c, s) =>
|
||||
new C3Ry16Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ry16"), new C3ry16(s,_cardCage))
|
||||
},
|
||||
{
|
||||
"c3ry8",
|
||||
(c, s) =>
|
||||
new C3Ry8Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ry8"), new C3ry8(s,_cardCage))
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
GetCards();
|
||||
}
|
||||
|
||||
private void GetCards()
|
||||
{
|
||||
if (_config.Cards == null)
|
||||
{
|
||||
Debug.Console(0, this, "No card configuration for this device found");
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= CardSlots; i++)
|
||||
{
|
||||
string cardType;
|
||||
if (!_config.Cards.TryGetValue(i, out cardType))
|
||||
{
|
||||
Debug.Console(1, this, "No card found for slot {0}", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(cardType))
|
||||
{
|
||||
Debug.Console(0, this, "No card specified for slot {0}", i);
|
||||
return;
|
||||
}
|
||||
|
||||
Func<CenCi33, uint, C3CardControllerBase> cardBuilder;
|
||||
if (!_cardDict.TryGetValue(cardType.ToLower(), out cardBuilder))
|
||||
{
|
||||
Debug.Console(0, "Unable to find factory for 3-Series card type {0}.", cardType);
|
||||
return;
|
||||
}
|
||||
|
||||
var device = cardBuilder(_cardCage, i);
|
||||
|
||||
DeviceManager.AddDevice(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CenCi33Configuration
|
||||
{
|
||||
[JsonProperty("cards")]
|
||||
public Dictionary<uint, string> Cards { get; set; }
|
||||
}
|
||||
|
||||
public class CenCi33ControllerFactory : EssentialsDeviceFactory<CenCi33Controller>
|
||||
{
|
||||
public CenCi33ControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string> {"cenci33"};
|
||||
}
|
||||
#region Overrides of EssentialsDeviceFactory<CenCi33Controller>
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory attempting to build new CEN-CI-3");
|
||||
|
||||
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var ipId = controlProperties.IpIdInt;
|
||||
|
||||
var cardCage = new CenCi33(ipId, Global.ControlSystem);
|
||||
var config = dc.Properties.ToObject<CenCi33Configuration>();
|
||||
|
||||
return new CenCi33Controller(dc.Key, dc.Name, config, cardCage);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.ThreeSeriesCards;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
{
|
||||
[ConfigSnippet("\"properties\":{\"cards\":{\"1\":\"c3com3\",\"2\":\"c3ry16\",\"3\":\"c3ry8\"}}")]
|
||||
public class InternalCardCageController : EssentialsDevice
|
||||
{
|
||||
private const string CardKeyTemplate = "{0}-card{1}";
|
||||
private const string CardNameTemplate = "{0}:{1}:{2}";
|
||||
private const uint CardSlots = 3;
|
||||
|
||||
private readonly InternalCardCageConfiguration _config;
|
||||
|
||||
private readonly Dictionary<string, Func<uint, C3CardControllerBase>> _cardDict;
|
||||
|
||||
public InternalCardCageController(string key, string name, InternalCardCageConfiguration config) : base(key, name)
|
||||
{
|
||||
_config = config;
|
||||
|
||||
_cardDict = new Dictionary<string, Func<uint, C3CardControllerBase>>
|
||||
{
|
||||
{
|
||||
"c3com3",
|
||||
(s) =>
|
||||
new C3Com3Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Com3"), new C3com3(s,Global.ControlSystem))
|
||||
},
|
||||
{
|
||||
"c3io16",
|
||||
(s) =>
|
||||
new C3Io16Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Io16"), new C3io16(s,Global.ControlSystem))
|
||||
},
|
||||
{
|
||||
"c3ir8",
|
||||
(s) =>
|
||||
new C3Ir8Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ir8"), new C3ir8(s,Global.ControlSystem))
|
||||
},
|
||||
{
|
||||
"c3ry16",
|
||||
(s) =>
|
||||
new C3Ry16Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ry16"), new C3ry16(s,Global.ControlSystem))
|
||||
},
|
||||
{
|
||||
"c3ry8",
|
||||
(s) =>
|
||||
new C3Ry8Controller(String.Format(CardKeyTemplate, key, s),
|
||||
String.Format(CardNameTemplate, key, s, "C3Ry8"), new C3ry8(s,Global.ControlSystem))
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
GetCards();
|
||||
}
|
||||
|
||||
private void GetCards()
|
||||
{
|
||||
if (_config.Cards == null)
|
||||
{
|
||||
Debug.Console(0, this, "No card configuration for this device found");
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= CardSlots; i++)
|
||||
{
|
||||
string cardType;
|
||||
if (!_config.Cards.TryGetValue(i, out cardType))
|
||||
{
|
||||
Debug.Console(1, this, "No card found for slot {0}", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(cardType))
|
||||
{
|
||||
Debug.Console(0, this, "No card specified for slot {0}", i);
|
||||
return;
|
||||
}
|
||||
|
||||
Func<uint, C3CardControllerBase> cardBuilder;
|
||||
if (!_cardDict.TryGetValue(cardType.ToLower(), out cardBuilder))
|
||||
{
|
||||
Debug.Console(0, "Unable to find factory for 3-Series card type {0}.", cardType);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var device = cardBuilder(i);
|
||||
|
||||
|
||||
DeviceManager.AddDevice(device);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Unable to add card {0} to internal card cage.\r\nError Message: {1}\r\nStack Trace: {2}",
|
||||
cardType, ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalCardCageConfiguration
|
||||
{
|
||||
[JsonProperty("cards")]
|
||||
public Dictionary<uint, string> Cards { get; set; }
|
||||
}
|
||||
|
||||
public class InternalCardCageControllerFactory : EssentialsDeviceFactory<InternalCardCageController>
|
||||
{
|
||||
public InternalCardCageControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string> {"internalcardcage"};
|
||||
}
|
||||
#region Overrides of EssentialsDeviceFactory<InternalCardCageController>
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory attempting to build new Internal Card Cage Controller");
|
||||
|
||||
if (!Global.ControlSystem.SupportsThreeSeriesPlugInCards)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning, "Current control system does NOT support 3-Series cards. Everything is NOT awesome.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var config = dc.Properties.ToObject<InternalCardCageConfiguration>();
|
||||
|
||||
return new InternalCardCageController(dc.Key, dc.Name, config);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,14 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -148,7 +148,14 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericRelayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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.");
|
||||
}
|
||||
|
||||
if (RelayOutput == null)
|
||||
{
|
||||
|
||||
@@ -118,7 +118,14 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<StatusSignControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
|
||||
@@ -43,7 +43,10 @@ namespace PepperDash.Essentials.Core
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate steps on all Device class items
|
||||
@@ -299,5 +302,81 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
com.SimulateReceive(match.Groups[2].Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to set the debug level of a device
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SetDeviceStreamDebugging(string s)
|
||||
{
|
||||
var args = s.Split(' ');
|
||||
|
||||
var deviceKey = args[0];
|
||||
var setting = args[1];
|
||||
|
||||
var timeout= String.Empty;
|
||||
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
timeout = args[2];
|
||||
}
|
||||
|
||||
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
|
||||
try
|
||||
{
|
||||
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var min = Convert.ToUInt32(timeout);
|
||||
|
||||
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets stream debugging settings to off for all devices
|
||||
/// </summary>
|
||||
public static void DisableAllDeviceStreamDebugging()
|
||||
{
|
||||
foreach (var device in AllDevices)
|
||||
{
|
||||
var streamDevice = device as IStreamDebugging;
|
||||
|
||||
if (streamDevice != null)
|
||||
{
|
||||
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,236 +1,236 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Description("Wrapper class for a Basic IR Display")]
|
||||
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
||||
{
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get { return () => _IsCoolingDown; }
|
||||
}
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
{
|
||||
get { return () => _IsWarmingUp; }
|
||||
}
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||
: base(key, name)
|
||||
{
|
||||
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
|
||||
DeviceManager.AddDevice(IrPort);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += (o, a) => {
|
||||
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||
if (_PowerIsOn) StartWarmingTimer();
|
||||
else StartCoolingTimer();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
|
||||
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
|
||||
|
||||
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
|
||||
});
|
||||
}
|
||||
|
||||
public void Hdmi1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi2()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi3()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi4()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Component1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Video1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Antenna()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
||||
}
|
||||
|
||||
#region IPower Members
|
||||
|
||||
public override void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||
_PowerIsOn = true;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public override void PowerOff()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
||||
}
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
void StartWarmingTimer()
|
||||
{
|
||||
_IsWarmingUp = true;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
new CTimer(o => {
|
||||
_IsWarmingUp = false;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
void StartCoolingTimer()
|
||||
{
|
||||
_IsCoolingDown = true;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
new CTimer(o =>
|
||||
{
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}, 7000);
|
||||
}
|
||||
|
||||
#region IRoutingSink Members
|
||||
|
||||
/// <summary>
|
||||
/// Typically called by the discovery routing algorithm.
|
||||
/// </summary>
|
||||
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
||||
public override void ExecuteSwitch(object inputSelector)
|
||||
{
|
||||
Debug.Console(2, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
|
||||
|
||||
Action finishSwitch = () =>
|
||||
{
|
||||
var action = inputSelector as Action;
|
||||
if (action != null)
|
||||
action();
|
||||
};
|
||||
|
||||
if (!PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
PowerOn();
|
||||
EventHandler<FeedbackEventArgs> oneTimer = null;
|
||||
oneTimer = (o, a) =>
|
||||
{
|
||||
if (IsWarmingUpFeedback.BoolValue) return; // Only catch done warming
|
||||
IsWarmingUpFeedback.OutputChange -= oneTimer;
|
||||
finishSwitch();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += oneTimer;
|
||||
}
|
||||
else // Do it!
|
||||
finishSwitch();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
}
|
||||
|
||||
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
||||
{
|
||||
public BasicIrDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "basicirdisplay" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new BasicIrDisplay Device");
|
||||
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
||||
if (ir != null)
|
||||
{
|
||||
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
||||
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
||||
return display;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class BasicIrDisplay : DisplayBase, IBasicVolumeControls, IBridgeAdvanced
|
||||
{
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get { return () => _IsCoolingDown; }
|
||||
}
|
||||
protected override Func<bool> IsWarmingUpFeedbackFunc
|
||||
{
|
||||
get { return () => _IsWarmingUp; }
|
||||
}
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
public BasicIrDisplay(string key, string name, IROutputPort port, string irDriverFilepath)
|
||||
: base(key, name)
|
||||
{
|
||||
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
|
||||
DeviceManager.AddDevice(IrPort);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += (o, a) => {
|
||||
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||
if (_PowerIsOn) StartWarmingTimer();
|
||||
else StartCoolingTimer();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
|
||||
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
|
||||
|
||||
InputPorts.AddRange(new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi2), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn3, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi3), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.HdmiIn4, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Hdmi4), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.ComponentIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Component1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.CompositeIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Video1), this, false),
|
||||
new RoutingInputPort(RoutingPortNames.AntennaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(Antenna), this, false),
|
||||
});
|
||||
}
|
||||
|
||||
public void Hdmi1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi2()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_2, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi3()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_3, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Hdmi4()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_HDMI_4, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Component1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_COMPONENT_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Video1()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_VIDEO_1, IrPulseTime);
|
||||
}
|
||||
|
||||
public void Antenna()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_ANTENNA, IrPulseTime);
|
||||
}
|
||||
|
||||
#region IPower Members
|
||||
|
||||
public override void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||
_PowerIsOn = true;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public override void PowerOff()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IBasicVolumeControls Members
|
||||
|
||||
public void VolumeUp(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_PLUS, pressRelease);
|
||||
}
|
||||
|
||||
public void VolumeDown(bool pressRelease)
|
||||
{
|
||||
IrPort.PressRelease(IROutputStandardCommands.IROut_VOL_MINUS, pressRelease);
|
||||
}
|
||||
|
||||
public void MuteToggle()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_MUTE, 200);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
void StartWarmingTimer()
|
||||
{
|
||||
_IsWarmingUp = true;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
new CTimer(o => {
|
||||
_IsWarmingUp = false;
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
void StartCoolingTimer()
|
||||
{
|
||||
_IsCoolingDown = true;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
new CTimer(o =>
|
||||
{
|
||||
_IsCoolingDown = false;
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
}, 7000);
|
||||
}
|
||||
|
||||
#region IRoutingSink Members
|
||||
|
||||
/// <summary>
|
||||
/// Typically called by the discovery routing algorithm.
|
||||
/// </summary>
|
||||
/// <param name="inputSelector">A delegate containing the input selector method to call</param>
|
||||
public override void ExecuteSwitch(object inputSelector)
|
||||
{
|
||||
Debug.Console(2, this, "Switching to input '{0}'", (inputSelector as Action).ToString());
|
||||
|
||||
Action finishSwitch = () =>
|
||||
{
|
||||
var action = inputSelector as Action;
|
||||
if (action != null)
|
||||
action();
|
||||
};
|
||||
|
||||
if (!PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
PowerOn();
|
||||
EventHandler<FeedbackEventArgs> oneTimer = null;
|
||||
oneTimer = (o, a) =>
|
||||
{
|
||||
if (IsWarmingUpFeedback.BoolValue) return; // Only catch done warming
|
||||
IsWarmingUpFeedback.OutputChange -= oneTimer;
|
||||
finishSwitch();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += oneTimer;
|
||||
}
|
||||
else // Do it!
|
||||
finishSwitch();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
}
|
||||
}
|
||||
|
||||
public class BasicIrDisplayFactory : EssentialsDeviceFactory<BasicIrDisplay>
|
||||
{
|
||||
public BasicIrDisplayFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "basicirdisplay" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new BasicIrDisplay Device");
|
||||
var ir = IRPortHelper.GetIrPort(dc.Properties);
|
||||
if (ir != null)
|
||||
{
|
||||
var display = new BasicIrDisplay(dc.Key, dc.Name, ir.Port, ir.FileName);
|
||||
display.IrPulseTime = 200; // Set default pulse time for IR commands.
|
||||
return display;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -128,9 +128,16 @@ namespace PepperDash.Essentials.Core
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
|
||||
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
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, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace PepperDash.Essentials.Core
|
||||
// Check for types that have been added by plugin dlls.
|
||||
if (FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from plugin", dc.Type);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
||||
return FactoryMethods[typeName].FactoryMethod(dc);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,9 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// Default poll time is 5 min unless overridden by config value
|
||||
public long SchedulePollInterval = 300000;
|
||||
|
||||
public long PushNotificationTimeout = 5000;
|
||||
public long PushNotificationTimeout = 5000;
|
||||
|
||||
private const string RemoteOccupancyXml = "<Occupancy><Type>Local</Type><State>{0}</State></Occupancy>";
|
||||
|
||||
protected Dictionary<int, FusionAsset> FusionStaticAssets;
|
||||
|
||||
@@ -115,7 +117,10 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
// For use with occ sensor attached to a scheduling panel in Fusion
|
||||
protected FusionOccupancySensorAsset FusionOccSensor;
|
||||
|
||||
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
|
||||
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
|
||||
|
||||
private string _roomOccupancyRemoteString;
|
||||
public StringFeedback RoomOccupancyRemoteStringFeedback { get; private set; }
|
||||
|
||||
protected Func<bool> RoomIsOccupiedFeedbackFunc
|
||||
{
|
||||
@@ -1365,14 +1370,24 @@ namespace PepperDash.Essentials.Core.Fusion
|
||||
var occSensorShutdownMinutes = FusionRoom.CreateOffsetUshortSig(70, "Occ Shutdown - Minutes", eSigIoMask.InputOutputSig);
|
||||
|
||||
// Tie to method on occupancy object
|
||||
//occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
|
||||
//occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
|
||||
|
||||
|
||||
RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString);
|
||||
Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
|
||||
Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
|
||||
RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig);
|
||||
|
||||
|
||||
Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
}
|
||||
|
||||
void RoomIsOccupiedFeedback_OutputChange(object sender, FeedbackEventArgs e)
|
||||
{
|
||||
_roomOccupancyRemoteString = String.Format(RemoteOccupancyXml, e.BoolValue ? "Occupied" : "Unoccupied");
|
||||
RoomOccupancyRemoteStringFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to get the number from the end of a device's key string
|
||||
/// </summary>
|
||||
/// <returns>-1 if no number matched</returns>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
using PepperDash.Core;
|
||||
@@ -345,8 +346,10 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
/// Metadata describing the join
|
||||
/// </summary>
|
||||
public class JoinMetadata
|
||||
{
|
||||
public class JoinMetadata
|
||||
{
|
||||
private string _description;
|
||||
|
||||
/// <summary>
|
||||
/// Join number (based on join offset value)
|
||||
/// </summary>
|
||||
@@ -361,10 +364,17 @@ namespace PepperDash.Essentials.Core
|
||||
public uint JoinSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A label for the join to better describe it's usage
|
||||
/// A label for the join to better describe its usage
|
||||
/// </summary>
|
||||
[JsonProperty("label")]
|
||||
public string Label { get; set; }
|
||||
[Obsolete("Use Description instead")]
|
||||
[JsonProperty("label")]
|
||||
public string Label { get { return _description; } set { _description = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// A description for the join to better describe its usage
|
||||
/// </summary>
|
||||
[JsonProperty("description")]
|
||||
public string Description { get { return _description; } set { _description = value; } }
|
||||
/// <summary>
|
||||
/// Signal type(s)
|
||||
/// </summary>
|
||||
@@ -454,11 +464,13 @@ namespace PepperDash.Essentials.Core
|
||||
name = attribute.Name;
|
||||
Debug.Console(2, "JoinName Attribute value: {0}", name);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
public class JoinNameAttribute : Attribute
|
||||
public class JoinNameAttribute : CAttribute
|
||||
{
|
||||
private string _Name;
|
||||
|
||||
@@ -472,5 +484,5 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
get { return _Name; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,14 @@ namespace PepperDash.Essentials.Core.Lighting
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericLightingJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
|
||||
@@ -209,7 +209,14 @@ namespace PepperDash.Essentials.Core.Monitoring
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<SystemMonitorJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(2, this, "Linking API starting at join: {0}", joinStart);
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
</Reference>
|
||||
<Reference Include="Crestron.SimplSharpPro.Gateways, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath>
|
||||
<HintPath>..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Gateways.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Crestron.SimplSharpPro.GeneralIO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -74,6 +74,10 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Crestron.SimplSharpPro.ThreeSeriesCards, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.ThreeSeriesCards.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Crestron.SimplSharpPro.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
|
||||
@@ -141,21 +145,32 @@
|
||||
<Compile Include="Bridges\JoinMaps\SetTopBoxControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\StatusSignControllerJoinMap.cs" />
|
||||
<Compile Include="Bridges\JoinMaps\SystemMonitorJoinMap.cs" />
|
||||
<Compile Include="Config\Comm and IR\CecPortController.cs" />
|
||||
<Compile Include="Config\Comm and IR\CommFactory.cs" />
|
||||
<Compile Include="Config\Comm and IR\CommunicationExtras.cs" />
|
||||
<Compile Include="Config\Comm and IR\ComPortController.cs" />
|
||||
<Compile Include="Config\Comm and IR\ComSpecJsonConverter.cs" />
|
||||
<Compile Include="Config\Comm and IR\ConsoleCommMockDevice.cs" />
|
||||
<Compile Include="Config\Comm and IR\GenericComm.cs" />
|
||||
<Compile Include="Config\Comm and IR\GenericHttpClient.cs" />
|
||||
<Compile Include="Config\Comm and IR\IRPortHelper.cs" />
|
||||
<Compile Include="Comm and IR\CecPortController.cs" />
|
||||
<Compile Include="Comm and IR\CommFactory.cs" />
|
||||
<Compile Include="Comm and IR\CommunicationExtras.cs" />
|
||||
<Compile Include="Comm and IR\ComPortController.cs" />
|
||||
<Compile Include="Comm and IR\ComSpecJsonConverter.cs" />
|
||||
<Compile Include="Comm and IR\ConsoleCommMockDevice.cs" />
|
||||
<Compile Include="Comm and IR\GenericComm.cs" />
|
||||
<Compile Include="Comm and IR\GenericHttpClient.cs" />
|
||||
<Compile Include="Comm and IR\IRPortHelper.cs" />
|
||||
<Compile Include="Config\Essentials\ConfigUpdater.cs" />
|
||||
<Compile Include="Config\Essentials\ConfigReader.cs" />
|
||||
<Compile Include="Config\Essentials\ConfigWriter.cs" />
|
||||
<Compile Include="Config\Essentials\EssentialsConfig.cs" />
|
||||
<Compile Include="Config\SourceDevicePropertiesConfigBase.cs" />
|
||||
<Compile Include="Crestron IO\C2nRts\C2nRthsController.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3CardControllerBase.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3Com3Controller.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3Io16Controller.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3Ir8Controller.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3Ry16Controller.cs" />
|
||||
<Compile Include="Crestron IO\Cards\C3Ry8Controller.cs" />
|
||||
<Compile Include="Crestron IO\Cards\CenCi31Controller.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Crestron IO\Cards\CenCi33Controller.cs" />
|
||||
<Compile Include="Crestron IO\Cards\InternalCardCageController.cs" />
|
||||
<Compile Include="Crestron IO\Inputs\CenIoDigIn104Controller.cs" />
|
||||
<Compile Include="Crestron IO\Inputs\GenericDigitalInputDevice.cs" />
|
||||
<Compile Include="Crestron IO\Inputs\GenericVersiportInputDevice.cs" />
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, PepperDash.Essentials.Core.Bridges.EiscApiAdvanced bridge)
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new Hrxxx0WirelessRemoteControllerJoinMap(joinStart);
|
||||
|
||||
@@ -158,36 +158,49 @@ namespace PepperDash.Essentials.Core
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<Hrxxx0WirelessRemoteControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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.");
|
||||
}
|
||||
|
||||
//List<string> ExcludedKeys = new List<string>();
|
||||
|
||||
|
||||
|
||||
foreach (Feedback feedback in Feedbacks)
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
Feedback myFeedback = feedback;
|
||||
var myFeedback = feedback;
|
||||
|
||||
var join = joinMap.Joins.FirstOrDefault(x => x.Value.Metadata.Label.Equals(myFeedback.Key, StringComparison.InvariantCultureIgnoreCase)).Value;
|
||||
var joinData =
|
||||
joinMap.Joins.FirstOrDefault(
|
||||
x =>
|
||||
x.Key.Equals(myFeedback.Key, StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (join == null) continue;
|
||||
if (string.IsNullOrEmpty((joinData.Key))) continue;
|
||||
|
||||
var name = joinData.Key;
|
||||
var join = joinData.Value;
|
||||
|
||||
if (join.Metadata.JoinType == eJoinType.Digital)
|
||||
{
|
||||
Debug.Console(0, this, "Linking Bool Feedback '{0}' to join {1}", join.Metadata.Label, join.JoinNumber);
|
||||
BoolFeedback someFeedback = myFeedback as BoolFeedback;
|
||||
Debug.Console(0, this, "Linking Bool Feedback '{0}' to join {1}", name, join.JoinNumber);
|
||||
var someFeedback = myFeedback as BoolFeedback;
|
||||
if(someFeedback == null) continue;
|
||||
someFeedback.LinkInputSig(trilist.BooleanInput[join.JoinNumber]);
|
||||
}
|
||||
if (join.Metadata.JoinType == eJoinType.Analog)
|
||||
{
|
||||
Debug.Console(0, this, "Linking Analog Feedback '{0}' to join {1}", join.Metadata.Label, join.JoinNumber);
|
||||
IntFeedback someFeedback = myFeedback as IntFeedback;
|
||||
Debug.Console(0, this, "Linking Analog Feedback '{0}' to join {1}", name, join.JoinNumber);
|
||||
var someFeedback = myFeedback as IntFeedback;
|
||||
if (someFeedback == null) continue;
|
||||
someFeedback.LinkInputSig(trilist.UShortInput[join.JoinNumber]);
|
||||
}
|
||||
if (join.Metadata.JoinType == eJoinType.Serial)
|
||||
{
|
||||
Debug.Console(0, this, "Linking Serial Feedback '{0}' to join {1}", join.Metadata.Label, join.JoinNumber);
|
||||
StringFeedback someFeedback = myFeedback as StringFeedback;
|
||||
Debug.Console(0, this, "Linking Serial Feedback '{0}' to join {1}", name, join.JoinNumber);
|
||||
var someFeedback = myFeedback as StringFeedback;
|
||||
if (someFeedback == null) continue;
|
||||
someFeedback.LinkInputSig(trilist.StringInput[join.JoinNumber]);
|
||||
}
|
||||
}
|
||||
@@ -201,13 +214,19 @@ namespace PepperDash.Essentials.Core
|
||||
for (uint i = 1; i <= _remote.Button.Count; i++)
|
||||
{
|
||||
Debug.Console(2, this, "Attempting to link join index {0}", i);
|
||||
var join = joinMap.Joins.FirstOrDefault(o => o.Value.Metadata.Label.Equals(_remote.Button[i].Name.ToString(), StringComparison.InvariantCultureIgnoreCase)).Value;
|
||||
if (join == null)
|
||||
{
|
||||
Debug.Console(2, this, "Join '{0}' is null", i);
|
||||
continue;
|
||||
}
|
||||
Debug.Console(2, this, "Setting User Object for '{0}'", join.Metadata.Label);
|
||||
var index = i;
|
||||
var joinData =
|
||||
joinMap.Joins.FirstOrDefault(
|
||||
o =>
|
||||
o.Key.Equals(_remote.Button[index].Name.ToString(),
|
||||
StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (string.IsNullOrEmpty((joinData.Key))) continue;
|
||||
|
||||
var join = joinData.Value;
|
||||
var name = joinData.Key;
|
||||
|
||||
Debug.Console(2, this, "Setting User Object for '{0}'", name);
|
||||
if (join.Metadata.JoinType == eJoinType.Digital)
|
||||
{
|
||||
_remote.Button[i].SetButtonAction((b) => trilist.BooleanInput[join.JoinNumber].BoolValue = b);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// and then attempts a new Route and if sucessful, stores that RouteDescriptor
|
||||
/// in RouteDescriptorCollection.DefaultCollection
|
||||
/// </summary>
|
||||
public static void ReleaseAndMakeRoute(this IRoutingInputs destination, IRoutingOutputs source, eRoutingSignalType signalType)
|
||||
public static void ReleaseAndMakeRoute(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
|
||||
{
|
||||
destination.ReleaseRoute();
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// RouteDescriptorCollection.DefaultCollection
|
||||
/// </summary>
|
||||
/// <param name="destination"></param>
|
||||
public static void ReleaseRoute(this IRoutingInputs destination)
|
||||
public static void ReleaseRoute(this IRoutingSink destination)
|
||||
{
|
||||
var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination);
|
||||
if (current != null)
|
||||
@@ -56,7 +56,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// of an audio/video route are discovered a route descriptor is returned. If no route is
|
||||
/// discovered, then null is returned
|
||||
/// </summary>
|
||||
public static RouteDescriptor GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source, eRoutingSignalType signalType)
|
||||
public static RouteDescriptor GetRouteToSource(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
|
||||
{
|
||||
var routeDescr = new RouteDescriptor(source, destination, signalType);
|
||||
// if it's a single signal type, find the route
|
||||
@@ -152,7 +152,7 @@ namespace PepperDash.Essentials.Core
|
||||
if (outputPortToUse == null)
|
||||
{
|
||||
// it's a sink device
|
||||
routeTable.Routes.Add(new RouteSwitchDescriptor(goodInputPort));
|
||||
routeTable.Routes.Add(new RouteSwitchDescriptor(goodInputPort));
|
||||
}
|
||||
else if (destination is IRouting)
|
||||
{
|
||||
@@ -265,14 +265,20 @@ namespace PepperDash.Essentials.Core
|
||||
foreach (var route in Routes)
|
||||
{
|
||||
Debug.Console(2, "ExecuteRoutes: {0}", route.ToString());
|
||||
if (route.SwitchingDevice is IRoutingSinkWithSwitching)
|
||||
(route.SwitchingDevice as IRoutingSinkWithSwitching).ExecuteSwitch(route.InputPort.Selector);
|
||||
else if (route.SwitchingDevice is IRouting)
|
||||
{
|
||||
(route.SwitchingDevice as IRouting).ExecuteSwitch(route.InputPort.Selector, route.OutputPort.Selector, SignalType);
|
||||
route.OutputPort.InUseTracker.AddUser(Destination, "destination-" + SignalType);
|
||||
Debug.Console(2, "Output port {0} routing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
|
||||
}
|
||||
if (route.SwitchingDevice is IRoutingSink)
|
||||
{
|
||||
var device = route.SwitchingDevice as IRoutingSinkWithSwitching;
|
||||
if (device == null)
|
||||
continue;
|
||||
|
||||
device.ExecuteSwitch(route.InputPort.Selector);
|
||||
}
|
||||
else if (route.SwitchingDevice is IRouting)
|
||||
{
|
||||
(route.SwitchingDevice as IRouting).ExecuteSwitch(route.InputPort.Selector, route.OutputPort.Selector, SignalType);
|
||||
route.OutputPort.InUseTracker.AddUser(Destination, "destination-" + SignalType);
|
||||
Debug.Console(2, "Output port {0} routing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,109 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The handler type for a Room's SourceInfoChange
|
||||
/// </summary>
|
||||
public delegate void SourceInfoChangeHandler(/*EssentialsRoomBase room,*/ SourceListItem info, ChangeType type);
|
||||
|
||||
|
||||
//*******************************************************************************************
|
||||
// Interfaces
|
||||
|
||||
/// <summary>
|
||||
/// For rooms with a single presentation source, change event
|
||||
/// </summary>
|
||||
public interface IHasCurrentSourceInfoChange
|
||||
{
|
||||
string CurrentSourceInfoKey { get; set; }
|
||||
SourceListItem CurrentSourceInfo { get; set; }
|
||||
event SourceInfoChangeHandler CurrentSourceChange;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a class that has a collection of RoutingInputPorts
|
||||
/// </summary>
|
||||
public interface IRoutingInputs : IKeyed
|
||||
{
|
||||
RoutingPortCollection<RoutingInputPort> InputPorts { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a class that has a collection of RoutingOutputPorts
|
||||
/// </summary>
|
||||
|
||||
public interface IRoutingOutputs : IKeyed
|
||||
{
|
||||
RoutingPortCollection<RoutingOutputPort> OutputPorts { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For fixed-source endpoint devices
|
||||
/// </summary>
|
||||
public interface IRoutingSinkNoSwitching : IRoutingInputs, IHasCurrentSourceInfoChange
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint device like a display, that selects inputs
|
||||
/// </summary>
|
||||
public interface IRoutingSinkWithSwitching : IRoutingSinkNoSwitching, IHasCurrentSourceInfoChange
|
||||
{
|
||||
//void ClearRoute();
|
||||
void ExecuteSwitch(object inputSelector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For devices like RMCs, baluns, other devices with no switching.
|
||||
/// </summary>
|
||||
public interface IRoutingInputsOutputs : IRoutingInputs, IRoutingOutputs
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a midpoint device as have internal routing. Any devices in the middle of the
|
||||
/// signal chain, that do switching, must implement this for routing to work otherwise
|
||||
/// the routing algorithm will treat the IRoutingInputsOutputs device as a passthrough
|
||||
/// device.
|
||||
/// </summary>
|
||||
public interface IRouting : IRoutingInputsOutputs
|
||||
{
|
||||
//void ClearRoute(object outputSelector);
|
||||
void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType);
|
||||
}
|
||||
|
||||
public interface ITxRouting : IRouting
|
||||
{
|
||||
IntFeedback VideoSourceNumericFeedback { get; }
|
||||
IntFeedback AudioSourceNumericFeedback { get; }
|
||||
void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type);
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The handler type for a Room's SourceInfoChange
|
||||
/// </summary>
|
||||
public delegate void SourceInfoChangeHandler(/*EssentialsRoomBase room,*/ SourceListItem info, ChangeType type);
|
||||
|
||||
|
||||
//*******************************************************************************************
|
||||
// Interfaces
|
||||
|
||||
/// <summary>
|
||||
/// For rooms with a single presentation source, change event
|
||||
/// </summary>
|
||||
public interface IHasCurrentSourceInfoChange
|
||||
{
|
||||
string CurrentSourceInfoKey { get; set; }
|
||||
SourceListItem CurrentSourceInfo { get; set; }
|
||||
event SourceInfoChangeHandler CurrentSourceChange;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a class that has a collection of RoutingInputPorts
|
||||
/// </summary>
|
||||
public interface IRoutingInputs : IKeyed
|
||||
{
|
||||
RoutingPortCollection<RoutingInputPort> InputPorts { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a class that has a collection of RoutingOutputPorts
|
||||
/// </summary>
|
||||
|
||||
public interface IRoutingOutputs : IKeyed
|
||||
{
|
||||
RoutingPortCollection<RoutingOutputPort> OutputPorts { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For fixed-source endpoint devices
|
||||
/// </summary>
|
||||
public interface IRoutingSink : IRoutingInputs, IHasCurrentSourceInfoChange
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For fixed-source endpoint devices
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public interface IRoutingSinkNoSwitching : IRoutingSink
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint device like a display, that selects inputs
|
||||
/// </summary>
|
||||
public interface IRoutingSinkWithSwitching : IRoutingSink
|
||||
{
|
||||
//void ClearRoute();
|
||||
void ExecuteSwitch(object inputSelector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For devices like RMCs, baluns, other devices with no switching.
|
||||
/// </summary>
|
||||
public interface IRoutingInputsOutputs : IRoutingInputs, IRoutingOutputs
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a midpoint device as have internal routing. Any devices in the middle of the
|
||||
/// signal chain, that do switching, must implement this for routing to work otherwise
|
||||
/// the routing algorithm will treat the IRoutingInputsOutputs device as a passthrough
|
||||
/// device.
|
||||
/// </summary>
|
||||
public interface IRouting : IRoutingInputsOutputs
|
||||
{
|
||||
void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType);
|
||||
}
|
||||
|
||||
public interface IRoutingNumeric : IRouting
|
||||
{
|
||||
void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type);
|
||||
}
|
||||
|
||||
public interface ITxRouting : IRoutingNumeric
|
||||
{
|
||||
IntFeedback VideoSourceNumericFeedback { get; }
|
||||
IntFeedback AudioSourceNumericFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a receiver that has internal routing (DM-RMC-4K-Z-SCALER-C)
|
||||
/// </summary>
|
||||
public interface IRmcRouting : IRouting
|
||||
public interface IRmcRouting : IRoutingNumeric
|
||||
{
|
||||
IntFeedback AudioVideoSourceNumericFeedback { get; }
|
||||
void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRoutingOutputs devices as being a source - the start of the chain
|
||||
/// </summary>
|
||||
public interface IRoutingSource : IRoutingOutputs
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an IRoutingOutputs devices as being a source - the start of the chain
|
||||
/// </summary>
|
||||
public interface IRoutingSource : IRoutingOutputs
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ using PepperDash.Essentials.Core.Config;
|
||||
namespace PepperDash.Essentials.DM.AirMedia
|
||||
{
|
||||
[Description("Wrapper class for an AM-200 or AM-300")]
|
||||
public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingInputsOutputs, IIROutputPorts, IComPorts
|
||||
public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingNumeric, IIROutputPorts, IComPorts
|
||||
{
|
||||
public AmX00 AirMedia { get; private set; }
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
public BoolFeedback AutomaticInputRoutingEnabledFeedback { get; private set; }
|
||||
|
||||
public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props)
|
||||
:base(key, name, device)
|
||||
: base(key, name, device)
|
||||
{
|
||||
AirMedia = device;
|
||||
|
||||
@@ -52,27 +52,30 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this));
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this));
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this));
|
||||
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.Video,
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this));
|
||||
|
||||
if (AirMedia is Am300)
|
||||
{
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this));
|
||||
}
|
||||
|
||||
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
|
||||
eRoutingPortConnectionType.Hdmi, null, this));
|
||||
|
||||
AirMedia.AirMedia.AirMediaChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(AirMedia_AirMediaChange);
|
||||
|
||||
IsInSessionFeedback = new BoolFeedback( new Func<bool>(() => AirMedia.AirMedia.StatusFeedback.UShortValue == 0 ));
|
||||
IsInSessionFeedback = new BoolFeedback(new Func<bool>(() => AirMedia.AirMedia.StatusFeedback.UShortValue == 0));
|
||||
ErrorFeedback = new IntFeedback(new Func<int>(() => AirMedia.AirMedia.ErrorFeedback.UShortValue));
|
||||
NumberOfUsersConnectedFeedback = new IntFeedback(new Func<int>(() => AirMedia.AirMedia.NumberOfUsersConnectedFeedback.UShortValue));
|
||||
LoginCodeFeedback = new IntFeedback(new Func<int>(() => AirMedia.AirMedia.LoginCodeFeedback.UShortValue));
|
||||
@@ -111,7 +114,14 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<AirMediaControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Airmedia: {0}", Name);
|
||||
@@ -203,7 +213,7 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
/// </summary>
|
||||
public void SelectDmIn()
|
||||
{
|
||||
AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.HDMI;
|
||||
AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.DM;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,7 +221,7 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
/// </summary>
|
||||
public void SelectHdmiIn()
|
||||
{
|
||||
AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.DM;
|
||||
AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.HDMI;
|
||||
}
|
||||
|
||||
public void SelectAirboardIn()
|
||||
@@ -260,6 +270,33 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType signalType)
|
||||
{
|
||||
if ((signalType & eRoutingSignalType.Video) != eRoutingSignalType.Video) return;
|
||||
if (!Enum.IsDefined(typeof (AmX00DisplayControl.eAirMediaX00VideoSource), input))
|
||||
{
|
||||
Debug.Console(2, this, "Invalid Video Source Index : {0}", input);
|
||||
return;
|
||||
}
|
||||
AirMedia.DisplayControl.VideoOut = (AmX00DisplayControl.eAirMediaX00VideoSource) input;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRouting Members
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
Debug.Console(2, this, "Input Selector = {0}", inputSelector.ToString());
|
||||
var handler = inputSelector as Action;
|
||||
if (handler == null) return;
|
||||
handler();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class AirMediaControllerFactory : EssentialsDeviceFactory<AirMediaController>
|
||||
@@ -283,7 +320,7 @@ namespace PepperDash.Essentials.DM.AirMedia
|
||||
amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am300(props.Control.IpIdInt, Global.ControlSystem);
|
||||
|
||||
return new AirMediaController(dc.Key, dc.Name, amDevice, dc, props);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,8 @@ namespace PepperDash.Essentials.DM {
|
||||
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
|
||||
///
|
||||
/// </summary>
|
||||
public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback {
|
||||
public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumeric
|
||||
{
|
||||
public DMChassisPropertiesConfig PropertiesConfig { get; set; }
|
||||
|
||||
public Switch Chassis { get; private set; }
|
||||
@@ -563,14 +564,23 @@ namespace PepperDash.Essentials.DM {
|
||||
var outCard = input == 0 ? null : Chassis.Outputs[output];
|
||||
|
||||
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
|
||||
if ((sigType | eRoutingSignalType.Video) == eRoutingSignalType.Video) {
|
||||
Chassis.VideoEnter.BoolValue = true;
|
||||
Chassis.Outputs[output].VideoOut = inCard;
|
||||
}
|
||||
if ((sigType | eRoutingSignalType.Video) != eRoutingSignalType.Video) return;
|
||||
Chassis.VideoEnter.BoolValue = true;
|
||||
Chassis.Outputs[output].VideoOut = inCard;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, sigType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new DmBladeChassisControllerJoinMap(joinStart);
|
||||
@@ -580,7 +590,14 @@ namespace PepperDash.Essentials.DM {
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmBladeChassisControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
@@ -599,7 +616,7 @@ namespace PepperDash.Essentials.DM {
|
||||
{
|
||||
Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot);
|
||||
var txKey = TxDictionary[ioSlot];
|
||||
var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as DmTxControllerBase;
|
||||
var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase;
|
||||
|
||||
var advancedTxDevice = basicTxDevice as DmTxControllerBase;
|
||||
|
||||
@@ -808,6 +825,7 @@ namespace PepperDash.Essentials.DM {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace PepperDash.Essentials.DM
|
||||
///
|
||||
/// </summary>
|
||||
[Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")]
|
||||
public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingInputsOutputs, IRouting, IHasFeedback
|
||||
public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumeric
|
||||
{
|
||||
public DMChassisPropertiesConfig PropertiesConfig { get; set; }
|
||||
|
||||
@@ -1094,6 +1094,15 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, sigType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new DmChassisControllerJoinMap(joinStart);
|
||||
@@ -1103,7 +1112,14 @@ namespace PepperDash.Essentials.DM
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmChassisControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
@@ -1154,9 +1170,9 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
Debug.Console(2, "Creating Tx Feedbacks {0}", ioSlot);
|
||||
var txKey = TxDictionary[ioSlot];
|
||||
var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as DmTxControllerBase;
|
||||
var basicTxDevice = DeviceManager.GetDeviceForKey(txKey) as BasicDmTxControllerBase;
|
||||
|
||||
var advancedTxDevice = basicTxDevice;
|
||||
var advancedTxDevice = basicTxDevice as DmTxControllerBase;
|
||||
|
||||
if (Chassis is DmMd8x8Cpu3 || Chassis is DmMd8x8Cpu3rps
|
||||
|| Chassis is DmMd16x16Cpu3 || Chassis is DmMd16x16Cpu3rps
|
||||
|
||||
@@ -111,7 +111,14 @@ namespace PepperDash.Essentials.DM
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmpsAudioOutputControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ using PepperDash.Essentials.DM.Config;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
public class DmpsRoutingController : EssentialsBridgeableDevice, IRouting, IHasFeedback
|
||||
{
|
||||
public class DmpsRoutingController : EssentialsBridgeableDevice, IRoutingNumeric, IHasFeedback
|
||||
{
|
||||
public CrestronControlSystem Dmps { get; set; }
|
||||
public ISystemControl SystemControl { get; private set; }
|
||||
@@ -163,7 +163,14 @@ namespace PepperDash.Essentials.DM
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmpsRoutingControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
@@ -661,8 +668,6 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
}
|
||||
}
|
||||
///
|
||||
/// </summary>
|
||||
void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString());
|
||||
@@ -724,10 +729,7 @@ namespace PepperDash.Essentials.DM
|
||||
{
|
||||
if (RouteOffTimers.ContainsKey(pnt))
|
||||
return;
|
||||
RouteOffTimers[pnt] = new CTimer(o =>
|
||||
{
|
||||
ExecuteSwitch(0, pnt.Number, pnt.Type);
|
||||
}, RouteOffTime);
|
||||
RouteOffTimers[pnt] = new CTimer(o => ExecuteSwitch(0, pnt.Number, pnt.Type), RouteOffTime);
|
||||
}
|
||||
|
||||
#region IRouting Members
|
||||
@@ -809,6 +811,15 @@ namespace PepperDash.Essentials.DM
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, sigType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ using PepperDash.Essentials.Core.Config;
|
||||
namespace PepperDash.Essentials.DM.Chassis
|
||||
{
|
||||
[Description("Wrapper class for all HdMdNxM4E switchers")]
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingInputsOutputs, IRouting, IHasFeedback
|
||||
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingInputsOutputs, IRoutingNumeric, IHasFeedback
|
||||
{
|
||||
private HdMdNxM _Chassis;
|
||||
private HdMd4x14kE _Chassis4x1;
|
||||
@@ -240,6 +240,15 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRoutingNumeric Members
|
||||
|
||||
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
ExecuteSwitch(inputSelector, outputSelector, signalType);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bridge Linking
|
||||
@@ -253,15 +262,23 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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.");
|
||||
}
|
||||
|
||||
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
|
||||
|
||||
if (_Chassis4x1 != null)
|
||||
{
|
||||
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
|
||||
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
|
||||
AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
|
||||
AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableAutoRoute.JoinNumber]);
|
||||
}
|
||||
|
||||
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
|
||||
@@ -389,6 +406,8 @@ namespace PepperDash.Essentials.DM.Chassis
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,14 @@ namespace PepperDash.Essentials.DM
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<HdMdxxxCEControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
|
||||
@@ -24,18 +24,31 @@ namespace PepperDash.Essentials.DM
|
||||
EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
|
||||
|
||||
_rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
|
||||
_rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
|
||||
|
||||
//removed to prevent NullReferenceException
|
||||
//_rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
|
||||
}
|
||||
|
||||
void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args)
|
||||
{
|
||||
if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId ||
|
||||
args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId)
|
||||
switch (args.EventId)
|
||||
{
|
||||
VideoOutputResolutionFeedback.FireUpdate();
|
||||
case EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId:
|
||||
case EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId:
|
||||
case EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId:
|
||||
VideoOutputResolutionFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointOutputStreamEventIds.HotplugDetectedEventId:
|
||||
if (_rmc.HdmiOutput.ConnectedDevice == null) return;
|
||||
EdidManufacturerFeedback.FireUpdate();
|
||||
EdidNameFeedback.FireUpdate();
|
||||
EdidPreferredTimingFeedback.FireUpdate();
|
||||
EdidSerialNumberFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
@@ -53,7 +66,7 @@ namespace PepperDash.Essentials.DM
|
||||
EdidSerialNumberFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,14 @@ namespace PepperDash.Essentials.DM
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmRmcControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
@@ -173,22 +180,22 @@ namespace PepperDash.Essentials.DM
|
||||
{"dmrmcscalers", (k, n,i, d) => new DmRmcScalerSController(k, n, new DmRmcScalerS(i,d))},
|
||||
{
|
||||
"dmrmcscalers2",
|
||||
(k, n,i, d) => new DmRmcScalerS2Controller(k, n, new DmRmcScalerS2(d))
|
||||
(k, n,i, d) => new DmRmcScalerS2Controller(k, n, new DmRmcScalerS2(i, d))
|
||||
},
|
||||
{
|
||||
"dmrmc4kscalerc",
|
||||
(k, n,i, d) => new DmRmc4kScalerCController(k, n, new DmRmc4kScalerC(d))
|
||||
(k, n,i, d) => new DmRmc4kScalerCController(k, n, new DmRmc4kScalerC(i, d))
|
||||
},
|
||||
{
|
||||
"dmrmc4kscalercdsp",
|
||||
(k, n,i, d) => new DmRmc4kScalerCDspController(k, n, new DmRmc4kScalerCDsp(d))
|
||||
(k, n,i, d) => new DmRmc4kScalerCDspController(k, n, new DmRmc4kScalerCDsp(i, d))
|
||||
},
|
||||
{
|
||||
"dmrmc4kzscalerc",
|
||||
(k, n,i, d) => new DmRmc4kZScalerCController(k, n, new DmRmc4kzScalerC(d))
|
||||
(k, n,i, d) => new DmRmc4kZScalerCController(k, n, new DmRmc4kzScalerC(i, d))
|
||||
},
|
||||
{"hdbasetrx", (k,n,i,d) => new HDBaseTRxController(k,n, new HDRx3CB(d))},
|
||||
{"dmrmc4k100c1g", (k,n,i,d) => new DmRmc4k100C1GController(k,n, new DmRmc4K100C1G(d))}
|
||||
{"hdbasetrx", (k,n,i,d) => new HDBaseTRxController(k,n, new HDRx3CB(i, d))},
|
||||
{"dmrmc4k100c1g", (k,n,i,d) => new DmRmc4k100C1GController(k,n, new DmRmc4K100C1G(i, d))}
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
@@ -307,7 +314,7 @@ namespace PepperDash.Essentials.DM
|
||||
TypeNames = new List<string>
|
||||
{ "hdbasetrx", "dmrmc4k100c1g", "dmrmc100c", "dmrmc100s", "dmrmc4k100c", "dmrmc150s",
|
||||
"dmrmc200c", "dmrmc200s", "dmrmc200s2", "dmrmcscalerc", "dmrmcscalers", "dmrmcscalers2", "dmrmc4kscalerc", "dmrmc4kscalercdsp",
|
||||
"dmrmc4kz100c", "dmrmckzscalerc" };
|
||||
"dmrmc4kz100c", "dmrmc4kzscalerc" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
using eVst = eX02VideoSourceType;
|
||||
using eAst = eX02AudioSourceType;
|
||||
|
||||
[Description("Wrapper class for DM-TX-4K-100-C-1G")]
|
||||
public class DmTx4k100Controller : DmTxControllerBase, IRoutingInputsOutputs,
|
||||
using eAst = eX02AudioSourceType;
|
||||
|
||||
public class DmTx4k100Controller : BasicDmTxControllerBase, IRoutingInputsOutputs,
|
||||
IIROutputPorts, IComPorts, ICec
|
||||
{
|
||||
public DmTx4K100C1G Tx { get; private set; }
|
||||
@@ -68,14 +68,13 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
// Set Ports for CEC
|
||||
HdmiIn.Port = Tx;
|
||||
}
|
||||
|
||||
PreventRegistration = true;
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
DmTxControllerJoinMap joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
|
||||
|
||||
LinkDmTxToApi(this, trilist, joinMap, bridge);
|
||||
Debug.Console(1, this, "No properties to link. Skipping device {0}", Name);
|
||||
}
|
||||
|
||||
#region IIROutputPorts Members
|
||||
@@ -91,7 +90,5 @@ namespace PepperDash.Essentials.DM
|
||||
#region ICec Members
|
||||
public Cec StreamCec { get { return Tx.StreamCec; } }
|
||||
#endregion
|
||||
|
||||
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,13 @@ using PepperDash.Essentials.DM.Config;
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
|
||||
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
|
||||
|
||||
[Description("Wrapper class for DM-TX-4K-202-C")]
|
||||
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
|
||||
|
||||
[Description("Wrapper class for DM-TX-4K-202-C")]
|
||||
public class DmTx4k202CController : DmTxControllerBase, ITxRouting, IHasFeedback,
|
||||
IIROutputPorts, IComPorts
|
||||
{
|
||||
public DmTx4kX02CBase Tx { get; private set; }
|
||||
public DmTx4k202C Tx { get; private set; }
|
||||
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
|
||||
@@ -81,7 +81,7 @@ namespace PepperDash.Essentials.DM
|
||||
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
|
||||
}
|
||||
}
|
||||
public DmTx4k202CController(string key, string name, DmTx4kX02CBase tx)
|
||||
public DmTx4k202CController(string key, string name, DmTx4k202C tx)
|
||||
: base(key, name, tx)
|
||||
{
|
||||
Tx = tx;
|
||||
@@ -99,8 +99,9 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
|
||||
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
|
||||
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
|
||||
@@ -190,24 +191,24 @@ namespace PepperDash.Essentials.DM
|
||||
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
|
||||
|
||||
if (Hdmi1VideoSyncFeedback != null)
|
||||
{
|
||||
{
|
||||
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (Hdmi2VideoSyncFeedback != null)
|
||||
{
|
||||
{
|
||||
Hdmi2VideoSyncFeedback.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 (type)
|
||||
{
|
||||
case eRoutingSignalType.Video:
|
||||
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
|
||||
{
|
||||
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case eRoutingSignalType.Video:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
@@ -230,9 +231,9 @@ namespace PepperDash.Essentials.DM
|
||||
ExecuteSwitch(eVst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eRoutingSignalType.Audio:
|
||||
}
|
||||
break;
|
||||
case eRoutingSignalType.Audio:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
@@ -255,11 +256,11 @@ namespace PepperDash.Essentials.DM
|
||||
ExecuteSwitch(eAst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
@@ -270,42 +271,42 @@ namespace PepperDash.Essentials.DM
|
||||
|
||||
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", this.Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
Debug.Console(2, "{0} event {1} stream {2}", this.Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
|
||||
{
|
||||
var id = args.EventId;
|
||||
Debug.Console(2, this, "EventId {0}", args.EventId);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
break;
|
||||
{
|
||||
var id = args.EventId;
|
||||
Debug.Console(2, this, "EventId {0}", args.EventId);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,12 +314,12 @@ namespace PepperDash.Essentials.DM
|
||||
/// Relays the input stream change to the appropriate RoutingInputPort.
|
||||
/// </summary>
|
||||
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
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;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
using eVst = eX02VideoSourceType;
|
||||
using eAst = eX02AudioSourceType;
|
||||
|
||||
public class DmTx4kz202CController : DmTxControllerBase, ITxRouting,
|
||||
IIROutputPorts, IComPorts
|
||||
{
|
||||
public DmTx4kz202C Tx { get; private set; }
|
||||
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
|
||||
public RoutingOutputPort DmOut { get; private set; }
|
||||
public RoutingOutputPort HdmiLoopOut { get; private set; }
|
||||
|
||||
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
|
||||
|
||||
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
|
||||
//public override ushort HdcpSupportCapability { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Helps get the "real" inputs, including when in Auto
|
||||
/// </summary>
|
||||
public eX02VideoSourceType ActualActiveVideoInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tx.VideoSourceFeedback != eVst.Auto)
|
||||
return Tx.VideoSourceFeedback;
|
||||
|
||||
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi1;
|
||||
|
||||
return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled;
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
HdmiIn1,
|
||||
HdmiIn2,
|
||||
AnyVideoInput
|
||||
};
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
|
||||
}
|
||||
}
|
||||
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
|
||||
: base(key, name, tx)
|
||||
{
|
||||
Tx = tx;
|
||||
|
||||
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
|
||||
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]));
|
||||
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
|
||||
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]));
|
||||
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
|
||||
() => ActualActiveVideoInput.ToString());
|
||||
|
||||
|
||||
|
||||
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
|
||||
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
//Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway
|
||||
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
|
||||
|
||||
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
var combinedFuncs = new VideoStatusFuncsWrapper
|
||||
{
|
||||
HdcpActiveFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
|
||||
|
||||
HdcpStateFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
return "";
|
||||
},
|
||||
|
||||
VideoResolutionFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
|
||||
return "";
|
||||
},
|
||||
VideoSyncFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].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);
|
||||
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
|
||||
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
|
||||
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
|
||||
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback);
|
||||
|
||||
// Set Ports for CEC
|
||||
HdmiIn1.Port = Tx.HdmiInputs[1];
|
||||
HdmiIn2.Port = Tx.HdmiInputs[2];
|
||||
HdmiLoopOut.Port = Tx.HdmiOutput;
|
||||
DmOut.Port = Tx.DmOutput;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Link up all of these damned events to the various RoutingPorts via a helper handler
|
||||
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
|
||||
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
|
||||
|
||||
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
|
||||
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, 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 (Hdmi1VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (Hdmi2VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi2VideoSyncFeedback.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 (type)
|
||||
{
|
||||
case eRoutingSignalType.Video:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExecuteSwitch(eVst.Auto, null, type);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn1.Selector, null, type);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn2.Selector, null, type);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(eVst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eRoutingSignalType.Audio:
|
||||
switch (input)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
ExecuteSwitch(eAst.Auto, null, type);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(eAst.Hdmi1, null, type);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(eAst.Hdmi2, null, type);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(eAst.AllDisabled, null, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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))
|
||||
Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
|
||||
}
|
||||
|
||||
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
|
||||
{
|
||||
var id = args.EventId;
|
||||
Debug.Console(2, this, "EventId {0}", args.EventId);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the input stream change to the appropriate RoutingInputPort.
|
||||
/// </summary>
|
||||
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -1,368 +1,360 @@
|
||||
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 = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
|
||||
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
|
||||
|
||||
[Description("Wrapper class for DM-TX-4K-Z-302-C")]
|
||||
public class DmTx4kz302CController : DmTxControllerBase, ITxRouting, IHasFeedback,
|
||||
IIROutputPorts, IComPorts
|
||||
{
|
||||
public DmTx4kz302C Tx { get; private set; }
|
||||
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; }
|
||||
public RoutingOutputPort DmOut { get; private set; }
|
||||
public RoutingOutputPort HdmiLoopOut { get; private set; }
|
||||
|
||||
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
|
||||
|
||||
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
|
||||
//public override ushort HdcpSupportCapability { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Helps get the "real" inputs, including when in Auto
|
||||
/// </summary>
|
||||
public Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType ActualActiveVideoInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tx.VideoSourceFeedback != eVst.Auto)
|
||||
return Tx.VideoSourceFeedback;
|
||||
else // auto
|
||||
{
|
||||
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi1;
|
||||
else if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi2;
|
||||
else if (Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Vga;
|
||||
else
|
||||
return eVst.AllDisabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
HdmiIn1,
|
||||
HdmiIn2,
|
||||
DisplayPortIn,
|
||||
AnyVideoInput
|
||||
};
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
|
||||
}
|
||||
}
|
||||
public DmTx4kz302CController(string key, string name, DmTx4kz302C tx)
|
||||
: base(key, name, tx)
|
||||
{
|
||||
Tx = tx;
|
||||
|
||||
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
|
||||
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]));
|
||||
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
|
||||
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]));
|
||||
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this,
|
||||
VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput));
|
||||
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
|
||||
() => ActualActiveVideoInput.ToString());
|
||||
|
||||
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange;
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
|
||||
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
|
||||
|
||||
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
|
||||
|
||||
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue);
|
||||
|
||||
|
||||
var combinedFuncs = new VideoStatusFuncsWrapper
|
||||
{
|
||||
HdcpActiveFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
|
||||
|
||||
HdcpStateFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
|
||||
},
|
||||
|
||||
VideoResolutionFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
|
||||
return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : "";
|
||||
},
|
||||
VideoSyncFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Vga
|
||||
&& tx.DisplayPortInput.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);
|
||||
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
|
||||
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
|
||||
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
|
||||
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback);
|
||||
|
||||
// Set Ports for CEC
|
||||
HdmiIn1.Port = Tx.HdmiInputs[1];
|
||||
HdmiIn2.Port = Tx.HdmiInputs[2];
|
||||
HdmiLoopOut.Port = Tx.HdmiOutput;
|
||||
DmOut.Port = Tx.DmOutput;
|
||||
}
|
||||
|
||||
void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
DisplayPortVideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Link up all of these damned events to the various RoutingPorts via a helper handler
|
||||
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
|
||||
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
|
||||
|
||||
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
|
||||
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
|
||||
|
||||
Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId);
|
||||
Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, 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 (Hdmi1VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (Hdmi2VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (DisplayPortVideoSyncFeedback != null)
|
||||
{
|
||||
DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.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, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn1.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn2.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(DisplayPortIn.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
Tx.VideoSource = (eVst)inputSelector;
|
||||
|
||||
// NOTE: It's possible that this particular TX model may not like the AudioSource property being set.
|
||||
// The SIMPL definition only shows a single analog for AudioVideo Source
|
||||
if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
|
||||
Tx.AudioSource = (eAst)inputSelector;
|
||||
}
|
||||
|
||||
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", this.Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
|
||||
{
|
||||
var id = args.EventId;
|
||||
switch (id)
|
||||
{
|
||||
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the input stream change to the appropriate RoutingInputPort.
|
||||
/// </summary>
|
||||
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
}
|
||||
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;
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
using eVst = eX02VideoSourceType;
|
||||
using eAst = eX02AudioSourceType;
|
||||
|
||||
|
||||
[Description("Wrapper class for DM-TX-4K-Z-302-C")]
|
||||
public class DmTx4kz302CController : DmTxControllerBase, ITxRouting, IHasFeedback,
|
||||
IIROutputPorts, IComPorts
|
||||
{
|
||||
public DmTx4kz302C Tx { get; private set; }
|
||||
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
|
||||
public RoutingInputPortWithVideoStatuses DisplayPortIn { get; private set; }
|
||||
public RoutingOutputPort DmOut { get; private set; }
|
||||
public RoutingOutputPort HdmiLoopOut { get; private set; }
|
||||
|
||||
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
|
||||
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
|
||||
public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
|
||||
|
||||
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
|
||||
//public override ushort HdcpSupportCapability { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Helps get the "real" inputs, including when in Auto
|
||||
/// </summary>
|
||||
public eX02VideoSourceType ActualActiveVideoInput
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Tx.VideoSourceFeedback != eVst.Auto)
|
||||
return Tx.VideoSourceFeedback;
|
||||
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi1;
|
||||
if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
|
||||
return eVst.Hdmi2;
|
||||
|
||||
return Tx.DisplayPortInput.SyncDetectedFeedback.BoolValue ? eVst.Vga : eVst.AllDisabled;
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingInputPort>
|
||||
{
|
||||
HdmiIn1,
|
||||
HdmiIn2,
|
||||
DisplayPortIn,
|
||||
AnyVideoInput
|
||||
};
|
||||
}
|
||||
}
|
||||
public RoutingPortCollection<RoutingOutputPort> OutputPorts
|
||||
{
|
||||
get
|
||||
{
|
||||
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
|
||||
}
|
||||
}
|
||||
public DmTx4kz302CController(string key, string name, DmTx4kz302C tx)
|
||||
: base(key, name, tx)
|
||||
{
|
||||
Tx = tx;
|
||||
|
||||
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
|
||||
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]));
|
||||
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
|
||||
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]));
|
||||
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
|
||||
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this,
|
||||
VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput));
|
||||
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
|
||||
() => ActualActiveVideoInput.ToString());
|
||||
|
||||
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
|
||||
Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange;
|
||||
Tx.BaseEvent += Tx_BaseEvent;
|
||||
|
||||
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
|
||||
|
||||
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
|
||||
|
||||
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
|
||||
|
||||
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
|
||||
|
||||
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
|
||||
|
||||
DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue);
|
||||
|
||||
|
||||
var combinedFuncs = new VideoStatusFuncsWrapper
|
||||
{
|
||||
HdcpActiveFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
|
||||
|
||||
HdcpStateFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
|
||||
return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
|
||||
},
|
||||
|
||||
VideoResolutionFeedbackFunc = () =>
|
||||
{
|
||||
if (ActualActiveVideoInput == eVst.Hdmi1)
|
||||
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
|
||||
if (ActualActiveVideoInput == eVst.Hdmi2)
|
||||
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
|
||||
return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : "";
|
||||
},
|
||||
VideoSyncFeedbackFunc = () =>
|
||||
(ActualActiveVideoInput == eVst.Hdmi1
|
||||
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Hdmi2
|
||||
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
|
||||
|| (ActualActiveVideoInput == eVst.Vga
|
||||
&& tx.DisplayPortInput.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);
|
||||
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
|
||||
eRoutingPortConnectionType.Hdmi, null, this);
|
||||
|
||||
|
||||
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
|
||||
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
|
||||
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
|
||||
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
|
||||
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback);
|
||||
|
||||
// Set Ports for CEC
|
||||
HdmiIn1.Port = Tx.HdmiInputs[1];
|
||||
HdmiIn2.Port = Tx.HdmiInputs[2];
|
||||
HdmiLoopOut.Port = Tx.HdmiOutput;
|
||||
DmOut.Port = Tx.DmOutput;
|
||||
}
|
||||
|
||||
void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
DisplayPortVideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
// Link up all of these damned events to the various RoutingPorts via a helper handler
|
||||
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
|
||||
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
|
||||
|
||||
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
|
||||
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
|
||||
|
||||
Tx.DisplayPortInput.InputStreamChange += (o, a) => FowardInputStreamChange(DisplayPortIn, a.EventId);
|
||||
Tx.DisplayPortInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(DisplayPortIn, 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 (Hdmi1VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (Hdmi2VideoSyncFeedback != null)
|
||||
{
|
||||
Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
|
||||
}
|
||||
if (DisplayPortVideoSyncFeedback != null)
|
||||
{
|
||||
DisplayPortVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.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, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn1.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
ExecuteSwitch(HdmiIn2.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
ExecuteSwitch(DisplayPortIn.Selector, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
ExecuteSwitch(eVst.AllDisabled, null, eRoutingSignalType.Audio | eRoutingSignalType.Video);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
|
||||
{
|
||||
if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
|
||||
Tx.VideoSource = (eVst)inputSelector;
|
||||
|
||||
// NOTE: It's possible that this particular TX model may not like the AudioSource property being set.
|
||||
// The SIMPL definition only shows a single analog for AudioVideo Source
|
||||
if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
|
||||
//it doesn't
|
||||
Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
|
||||
//Tx.AudioSource = (eAst)inputSelector;
|
||||
}
|
||||
|
||||
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
|
||||
{
|
||||
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
|
||||
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
|
||||
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
|
||||
{
|
||||
var id = args.EventId;
|
||||
switch (id)
|
||||
{
|
||||
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
|
||||
VideoSourceNumericFeedback.FireUpdate();
|
||||
ActiveVideoInputFeedback.FireUpdate();
|
||||
break;
|
||||
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
|
||||
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
|
||||
AudioSourceNumericFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Relays the input stream change to the appropriate RoutingInputPort.
|
||||
/// </summary>
|
||||
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
|
||||
{
|
||||
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
}
|
||||
}
|
||||
@@ -1,361 +1,373 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.DM.Config;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
public class DmTxHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// A factory method for various DmTxControllers
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="props"></param>
|
||||
/// <returns></returns>
|
||||
public static DmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props)
|
||||
{
|
||||
// switch on type name... later...
|
||||
|
||||
typeName = typeName.ToLower();
|
||||
//uint ipid = Convert.ToUInt16(props.Id, 16);
|
||||
var ipid = props.Control.IpIdInt;
|
||||
var pKey = props.ParentDeviceKey.ToLower();
|
||||
|
||||
if (pKey == "processor")
|
||||
{
|
||||
// Catch constructor failures, mainly dues to IPID
|
||||
try
|
||||
{
|
||||
if(typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4kz202C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem));
|
||||
Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var parentDev = DeviceManager.GetDeviceForKey(pKey);
|
||||
if (!(parentDev is IDmSwitch))
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.",
|
||||
key, pKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the Crestron chassis and link stuff up
|
||||
var switchDev = (parentDev as IDmSwitch);
|
||||
var chassis = switchDev.Chassis;
|
||||
|
||||
var num = props.ParentInputNumber;
|
||||
if (num <= 0 || num > chassis.NumberOfInputs)
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
|
||||
key, num);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var controller = (parentDev as IDmSwitch);
|
||||
controller.TxDictionary.Add(num, key);
|
||||
}
|
||||
|
||||
// Catch constructor failures, mainly dues to IPID
|
||||
try
|
||||
{
|
||||
// Must use different constructor for CPU3 chassis types. No IPID
|
||||
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
|
||||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
|
||||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps||
|
||||
chassis is DmMd128x128 || chassis is DmMd64x64)
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4kz202C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4kz202C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num]));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Description("Wrapper class for all DM-TX variants")]
|
||||
public abstract class DmTxControllerBase : CrestronGenericBridgeableBaseDevice
|
||||
{
|
||||
public virtual void SetPortHdcpCapability(eHdcpCapabilityType hdcpMode, uint port) { }
|
||||
public virtual eHdcpCapabilityType HdcpSupportCapability { get; protected set; }
|
||||
public abstract StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public RoutingInputPortWithVideoStatuses AnyVideoInput { get; protected set; }
|
||||
|
||||
protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
|
||||
: base(key, name, hardware)
|
||||
{
|
||||
// if wired to a chassis, skip registration step in base class
|
||||
if (hardware.DMInput != null)
|
||||
{
|
||||
this.PreventRegistration = true;
|
||||
}
|
||||
AddToFeedbackList(ActiveVideoInputFeedback);
|
||||
}
|
||||
|
||||
protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware)
|
||||
{
|
||||
}
|
||||
|
||||
protected DmTxControllerJoinMap GetDmTxJoinMap(uint joinStart, string joinMapKey)
|
||||
{
|
||||
var joinMap = new DmTxControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmTxControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
return joinMap;
|
||||
}
|
||||
|
||||
protected void LinkDmTxToApi(DmTxControllerBase tx, BasicTriList trilist, DmTxControllerJoinMap joinMap, EiscApiAdvanced bridge)
|
||||
{
|
||||
if (tx.Hardware is DmHDBasedTEndPoint)
|
||||
{
|
||||
Debug.Console(1, tx, "No properties to link. Skipping device {0}", tx.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber]);
|
||||
tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution.JoinNumber]);
|
||||
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)tx.HdcpSupportCapability;
|
||||
|
||||
bool hdcpTypeSimple;
|
||||
|
||||
if (tx.Hardware is DmTx4kX02CBase)
|
||||
hdcpTypeSimple = false;
|
||||
else
|
||||
hdcpTypeSimple = true;
|
||||
|
||||
if (tx is ITxRouting)
|
||||
{
|
||||
var txR = tx as ITxRouting;
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VideoInput.JoinNumber,
|
||||
i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Video));
|
||||
trilist.SetUShortSigAction(joinMap.AudioInput.JoinNumber,
|
||||
i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Audio));
|
||||
|
||||
txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput.JoinNumber]);
|
||||
txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput.JoinNumber]);
|
||||
|
||||
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)tx.HdcpSupportCapability;
|
||||
|
||||
if (txR.InputPorts[DmPortName.HdmiIn] != null)
|
||||
{
|
||||
var inputPort = txR.InputPorts[DmPortName.HdmiIn];
|
||||
|
||||
if (tx.Feedbacks["HdmiInHdcpCapability"] != null)
|
||||
{
|
||||
var intFeedback = tx.Feedbacks["HdmiInHdcpCapability"] as IntFeedback;
|
||||
if (intFeedback != null)
|
||||
intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
|
||||
}
|
||||
|
||||
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||
{
|
||||
var port = inputPort.Port as EndpointHdmiInput;
|
||||
|
||||
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState.JoinNumber, trilist);
|
||||
}
|
||||
}
|
||||
|
||||
if (txR.InputPorts[DmPortName.HdmiIn1] != null)
|
||||
{
|
||||
var inputPort = txR.InputPorts[DmPortName.HdmiIn1];
|
||||
|
||||
if (tx.Feedbacks["HdmiIn1HdcpCapability"] != null)
|
||||
{
|
||||
var intFeedback = tx.Feedbacks["HdmiIn1HdcpCapability"] as IntFeedback;
|
||||
if (intFeedback != null)
|
||||
intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
|
||||
}
|
||||
|
||||
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||
{
|
||||
var port = inputPort.Port as EndpointHdmiInput;
|
||||
|
||||
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState.JoinNumber, trilist);
|
||||
}
|
||||
}
|
||||
|
||||
if (txR.InputPorts[DmPortName.HdmiIn2] != null)
|
||||
{
|
||||
var inputPort = txR.InputPorts[DmPortName.HdmiIn2];
|
||||
|
||||
if (tx.Feedbacks["HdmiIn2HdcpCapability"] != null)
|
||||
{
|
||||
var intFeedback = tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback;
|
||||
if (intFeedback != null)
|
||||
intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
|
||||
}
|
||||
|
||||
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||
{
|
||||
var port = inputPort.Port as EndpointHdmiInput;
|
||||
|
||||
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port2HdcpState.JoinNumber, trilist);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var txFreeRun = tx as IHasFreeRun;
|
||||
if (txFreeRun != null)
|
||||
{
|
||||
txFreeRun.FreeRunEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FreeRunEnabled.JoinNumber]);
|
||||
trilist.SetBoolSigAction(joinMap.FreeRunEnabled.JoinNumber, txFreeRun.SetFreeRunEnabled);
|
||||
}
|
||||
|
||||
var txVga = tx as IVgaBrightnessContrastControls;
|
||||
{
|
||||
if (txVga == null) return;
|
||||
|
||||
txVga.VgaBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaBrightness.JoinNumber]);
|
||||
txVga.VgaContrastFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaContrast.JoinNumber]);
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VgaBrightness.JoinNumber, txVga.SetVgaBrightness);
|
||||
trilist.SetUShortSigAction(joinMap.VgaContrast.JoinNumber, txVga.SetVgaContrast);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)
|
||||
{
|
||||
if (hdcpTypeSimple)
|
||||
{
|
||||
trilist.SetUShortSigAction(join,
|
||||
s =>
|
||||
{
|
||||
if (s == 0)
|
||||
{
|
||||
port.HdcpSupportOff();
|
||||
}
|
||||
else if (s > 0)
|
||||
{
|
||||
port.HdcpSupportOn();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
trilist.SetUShortSigAction(join,
|
||||
s =>
|
||||
{
|
||||
port.HdcpCapability = (eHdcpCapabilityType)s;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DmTxControllerFactory : EssentialsDeviceFactory<DmTxControllerBase>
|
||||
{
|
||||
public DmTxControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "dmtx200c", "dmtx201c", "dmtx201s", "dmtx4k100c", "dmtx4k202c", "dmtx4kz202c", "dmtx4k302c", "dmtx4kz302c",
|
||||
"dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
var type = dc.Type.ToLower();
|
||||
|
||||
Debug.Console(1, "Factory Attempting to create new DM-TX Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject
|
||||
<PepperDash.Essentials.DM.Config.DmTxPropertiesConfig>(dc.Properties.ToString());
|
||||
return PepperDash.Essentials.DM.DmTxHelper.GetDmTxController(dc.Key, dc.Name, type, props);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.DM.Config;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.DM
|
||||
{
|
||||
public class DmTxHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// A factory method for various DmTxControllers
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="props"></param>
|
||||
/// <returns></returns>
|
||||
public static BasicDmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props)
|
||||
{
|
||||
// switch on type name... later...
|
||||
|
||||
typeName = typeName.ToLower();
|
||||
//uint ipid = Convert.ToUInt16(props.Id, 16);
|
||||
var ipid = props.Control.IpIdInt;
|
||||
var pKey = props.ParentDeviceKey.ToLower();
|
||||
|
||||
if (pKey == "processor")
|
||||
{
|
||||
// Catch constructor failures, mainly dues to IPID
|
||||
try
|
||||
{
|
||||
if(typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem));
|
||||
Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var parentDev = DeviceManager.GetDeviceForKey(pKey);
|
||||
if (!(parentDev is IDmSwitch))
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.",
|
||||
key, pKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the Crestron chassis and link stuff up
|
||||
var switchDev = (parentDev as IDmSwitch);
|
||||
var chassis = switchDev.Chassis;
|
||||
|
||||
var num = props.ParentInputNumber;
|
||||
if (num <= 0 || num > chassis.NumberOfInputs)
|
||||
{
|
||||
Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
|
||||
key, num);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var controller = (parentDev as IDmSwitch);
|
||||
controller.TxDictionary.Add(num, key);
|
||||
}
|
||||
|
||||
// Catch constructor failures, mainly dues to IPID
|
||||
try
|
||||
{
|
||||
// Must use different constructor for CPU3 chassis types. No IPID
|
||||
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
|
||||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
|
||||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps||
|
||||
chassis is DmMd128x128 || chassis is DmMd64x64)
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(chassis.Inputs[num]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeName.StartsWith("dmtx200"))
|
||||
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201c"))
|
||||
return new DmTx201CController(key, name, new DmTx201C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx201s"))
|
||||
return new DmTx201SController(key, name, new DmTx201S(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k100"))
|
||||
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz100"))
|
||||
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k202"))
|
||||
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz202"))
|
||||
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4k302"))
|
||||
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx4kz302"))
|
||||
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, chassis.Inputs[num]));
|
||||
if (typeName.StartsWith("dmtx401"))
|
||||
return new DmTx401CController(key, name, new DmTx401C(ipid, chassis.Inputs[num]));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BasicDmTxControllerBase : CrestronGenericBridgeableBaseDevice
|
||||
{
|
||||
protected BasicDmTxControllerBase(string key, string name, GenericBase hardware)
|
||||
: base(key, name, hardware)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Description("Wrapper class for all DM-TX variants")]
|
||||
public abstract class DmTxControllerBase : BasicDmTxControllerBase
|
||||
{
|
||||
public virtual void SetPortHdcpCapability(eHdcpCapabilityType hdcpMode, uint port) { }
|
||||
public virtual eHdcpCapabilityType HdcpSupportCapability { get; protected set; }
|
||||
public abstract StringFeedback ActiveVideoInputFeedback { get; protected set; }
|
||||
public RoutingInputPortWithVideoStatuses AnyVideoInput { get; protected set; }
|
||||
|
||||
protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
|
||||
: base(key, name, hardware)
|
||||
{
|
||||
// if wired to a chassis, skip registration step in base class
|
||||
if (hardware.DMInput != null)
|
||||
{
|
||||
this.PreventRegistration = true;
|
||||
}
|
||||
AddToFeedbackList(ActiveVideoInputFeedback);
|
||||
}
|
||||
|
||||
protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware)
|
||||
{
|
||||
}
|
||||
|
||||
protected DmTxControllerJoinMap GetDmTxJoinMap(uint joinStart, string joinMapKey)
|
||||
{
|
||||
var joinMap = new DmTxControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DmTxControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
return joinMap;
|
||||
}
|
||||
|
||||
protected void LinkDmTxToApi(DmTxControllerBase tx, BasicTriList trilist, DmTxControllerJoinMap joinMap, EiscApiAdvanced bridge)
|
||||
{
|
||||
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, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber]);
|
||||
tx.AnyVideoInput.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution.JoinNumber]);
|
||||
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)tx.HdcpSupportCapability;
|
||||
|
||||
bool hdcpTypeSimple;
|
||||
|
||||
if (tx.Hardware is DmTx4kX02CBase)
|
||||
hdcpTypeSimple = false;
|
||||
else
|
||||
hdcpTypeSimple = true;
|
||||
|
||||
if (tx is ITxRouting)
|
||||
{
|
||||
var txR = tx as ITxRouting;
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VideoInput.JoinNumber,
|
||||
i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Video));
|
||||
trilist.SetUShortSigAction(joinMap.AudioInput.JoinNumber,
|
||||
i => txR.ExecuteNumericSwitch(i, 0, eRoutingSignalType.Audio));
|
||||
|
||||
txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput.JoinNumber]);
|
||||
txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput.JoinNumber]);
|
||||
|
||||
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)tx.HdcpSupportCapability;
|
||||
|
||||
if (txR.InputPorts[DmPortName.HdmiIn] != null)
|
||||
{
|
||||
var inputPort = txR.InputPorts[DmPortName.HdmiIn];
|
||||
|
||||
if (tx.Feedbacks["HdmiInHdcpCapability"] != null)
|
||||
{
|
||||
var intFeedback = tx.Feedbacks["HdmiInHdcpCapability"] as IntFeedback;
|
||||
if (intFeedback != null)
|
||||
intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
|
||||
}
|
||||
|
||||
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||
{
|
||||
var port = inputPort.Port as EndpointHdmiInput;
|
||||
|
||||
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState.JoinNumber, trilist);
|
||||
}
|
||||
}
|
||||
|
||||
if (txR.InputPorts[DmPortName.HdmiIn1] != null)
|
||||
{
|
||||
var inputPort = txR.InputPorts[DmPortName.HdmiIn1];
|
||||
|
||||
if (tx.Feedbacks["HdmiIn1HdcpCapability"] != null)
|
||||
{
|
||||
var intFeedback = tx.Feedbacks["HdmiIn1HdcpCapability"] as IntFeedback;
|
||||
if (intFeedback != null)
|
||||
intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
|
||||
}
|
||||
|
||||
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||
{
|
||||
var port = inputPort.Port as EndpointHdmiInput;
|
||||
|
||||
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port1HdcpState.JoinNumber, trilist);
|
||||
}
|
||||
}
|
||||
|
||||
if (txR.InputPorts[DmPortName.HdmiIn2] != null)
|
||||
{
|
||||
var inputPort = txR.InputPorts[DmPortName.HdmiIn2];
|
||||
|
||||
if (tx.Feedbacks["HdmiIn2HdcpCapability"] != null)
|
||||
{
|
||||
var intFeedback = tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback;
|
||||
if (intFeedback != null)
|
||||
intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
|
||||
}
|
||||
|
||||
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
|
||||
{
|
||||
var port = inputPort.Port as EndpointHdmiInput;
|
||||
|
||||
SetHdcpCapabilityAction(hdcpTypeSimple, port, joinMap.Port2HdcpState.JoinNumber, trilist);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var txFreeRun = tx as IHasFreeRun;
|
||||
if (txFreeRun != null)
|
||||
{
|
||||
txFreeRun.FreeRunEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.FreeRunEnabled.JoinNumber]);
|
||||
trilist.SetBoolSigAction(joinMap.FreeRunEnabled.JoinNumber, txFreeRun.SetFreeRunEnabled);
|
||||
}
|
||||
|
||||
var txVga = tx as IVgaBrightnessContrastControls;
|
||||
{
|
||||
if (txVga == null) return;
|
||||
|
||||
txVga.VgaBrightnessFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaBrightness.JoinNumber]);
|
||||
txVga.VgaContrastFeedback.LinkInputSig(trilist.UShortInput[joinMap.VgaContrast.JoinNumber]);
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VgaBrightness.JoinNumber, txVga.SetVgaBrightness);
|
||||
trilist.SetUShortSigAction(joinMap.VgaContrast.JoinNumber, txVga.SetVgaContrast);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHdcpCapabilityAction(bool hdcpTypeSimple, EndpointHdmiInput port, uint join, BasicTriList trilist)
|
||||
{
|
||||
if (hdcpTypeSimple)
|
||||
{
|
||||
trilist.SetUShortSigAction(join,
|
||||
s =>
|
||||
{
|
||||
if (s == 0)
|
||||
{
|
||||
port.HdcpSupportOff();
|
||||
}
|
||||
else if (s > 0)
|
||||
{
|
||||
port.HdcpSupportOn();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
trilist.SetUShortSigAction(join,
|
||||
s =>
|
||||
{
|
||||
port.HdcpCapability = (eHdcpCapabilityType)s;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DmTxControllerFactory : EssentialsDeviceFactory<DmTxControllerBase>
|
||||
{
|
||||
public DmTxControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "dmtx200c", "dmtx201c", "dmtx201s", "dmtx4k100c", "dmtx4k202c", "dmtx4kz202c", "dmtx4k302c", "dmtx4kz302c",
|
||||
"dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
var type = dc.Type.ToLower();
|
||||
|
||||
Debug.Console(1, "Factory Attempting to create new DM-TX Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject
|
||||
<PepperDash.Essentials.DM.Config.DmTxPropertiesConfig>(dc.Properties.ToString());
|
||||
return PepperDash.Essentials.DM.DmTxHelper.GetDmTxController(dc.Key, dc.Name, type, props);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpReflectionInterface, Version=1.0.5583.25238, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -105,6 +105,7 @@
|
||||
<Compile Include="Endpoints\DGEs\DmDge200CController.cs" />
|
||||
<Compile Include="Endpoints\Receivers\DmRmc4kZ100CController.cs" />
|
||||
<Compile Include="Endpoints\Receivers\DmRmc4kZScalerCController.cs" />
|
||||
<Compile Include="Endpoints\Transmitters\DmTx4kz202CController.cs" />
|
||||
<Compile Include="Endpoints\Transmitters\DmTx201SController.cs" />
|
||||
<Compile Include="Endpoints\Transmitters\DmTx4kz100Controller.cs" />
|
||||
<Compile Include="Endpoints\Transmitters\TxInterfaces.cs" />
|
||||
|
||||
@@ -83,8 +83,14 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
|
||||
{
|
||||
CameraControllerJoinMap joinMap = new CameraControllerJoinMap(joinStart);
|
||||
|
||||
// Adds the join map to the bridge
|
||||
bridge.AddJoinMap(cameraDevice.Key, joinMap);
|
||||
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.");
|
||||
}
|
||||
|
||||
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||
|
||||
|
||||
@@ -447,7 +447,14 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<CenOdtOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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"));
|
||||
|
||||
|
||||
@@ -268,7 +268,14 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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"));
|
||||
|
||||
@@ -379,25 +386,13 @@ namespace PepperDash.Essentials.Devices.Common.Occupancy
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
|
||||
|
||||
var typeName = dc.Type.ToLower();
|
||||
var key = dc.Key;
|
||||
var name = dc.Name;
|
||||
var comm = CommFactory.GetControlPropertiesConfig(dc);
|
||||
|
||||
GlsOccupancySensorBase occSensor = null;
|
||||
|
||||
occSensor = new GlsOirCCn(comm.CresnetIdInt, Global.ControlSystem);
|
||||
|
||||
if (occSensor != null)
|
||||
{
|
||||
return new GlsOccupancySensorBaseController(key, name, occSensor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, "ERROR: Unable to create Occupancy Sensor Device. Key: '{0}'", key);
|
||||
return null;
|
||||
}
|
||||
GlsOccupancySensorBase occSensor = new GlsOirCCn(comm.CresnetIdInt, Global.ControlSystem);
|
||||
|
||||
return new GlsOccupancySensorBaseController(key, name, occSensor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -380,7 +380,14 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<SetTopBoxControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Display: {0}", Name);
|
||||
|
||||
@@ -153,7 +153,14 @@ namespace PepperDash.Essentials.Devices.Common
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<AppleTvJoinMap>(joinMapSerialized);
|
||||
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
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, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Bridge Type {0}", GetType().Name);
|
||||
|
||||
@@ -601,9 +601,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
//JsonSerializerSettings settings = new JsonSerializerSettings();
|
||||
//settings.NullValueHandling = NullValueHandling.Ignore;
|
||||
//settings.MissingMemberHandling = MissingMemberHandling.Ignore;
|
||||
//settings.ObjectCreationHandling = ObjectCreationHandling.Auto;
|
||||
|
||||
if (response.IndexOf("\"Status\":{") > -1)
|
||||
//settings.ObjectCreationHandling = ObjectCreationHandling.Auto;
|
||||
|
||||
if (response.IndexOf("\"Status\":{") > -1 || response.IndexOf("\"Status\": {") > -1)
|
||||
{
|
||||
// Status Message
|
||||
|
||||
@@ -775,8 +775,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
if (!SyncState.InitialConfigurationMessageWasReceived)
|
||||
SendText("xConfiguration");
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"Configuration\":{") > -1)
|
||||
}
|
||||
else if (response.IndexOf("\"Configuration\":{") > -1 || response.IndexOf("\"Configuration\": {") > -1)
|
||||
{
|
||||
// Configuration Message
|
||||
|
||||
@@ -791,39 +791,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (response.IndexOf("\"Event\":{") > -1)
|
||||
{
|
||||
if (response.IndexOf("\"CallDisconnect\":{") > -1)
|
||||
}
|
||||
else if (response.IndexOf("\"Event\":{") > -1 || response.IndexOf("\"Event\": {") > -1)
|
||||
{
|
||||
if (response.IndexOf("\"CallDisconnect\":{") > -1 || response.IndexOf("\"CallDisconnect\": {") > -1)
|
||||
{
|
||||
CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject();
|
||||
|
||||
JsonConvert.PopulateObject(response, eventReceived);
|
||||
|
||||
EvalutateDisconnectEvent(eventReceived);
|
||||
}
|
||||
else if (response.IndexOf("\"Bookings\":{") > -1) // The list has changed, reload it
|
||||
}
|
||||
else if (response.IndexOf("\"Bookings\":{") > -1 || response.IndexOf("\"Bookings\": {") > -1) // The list has changed, reload it
|
||||
{
|
||||
GetBookings(null);
|
||||
}
|
||||
}
|
||||
else if (response.IndexOf("\"CommandResponse\":{") > -1)
|
||||
}
|
||||
else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1)
|
||||
{
|
||||
// CommandResponse Message
|
||||
|
||||
if (response.IndexOf("\"CallHistoryRecentsResult\":{") > -1)
|
||||
// CommandResponse Message
|
||||
|
||||
if (response.IndexOf("\"CallHistoryRecentsResult\":{") > -1 || response.IndexOf("\"CallHistoryRecentsResult\": {") > -1)
|
||||
{
|
||||
var codecCallHistory = new CiscoCallHistory.RootObject();
|
||||
|
||||
JsonConvert.PopulateObject(response, codecCallHistory);
|
||||
|
||||
CallHistory.ConvertCiscoCallHistoryToGeneric(codecCallHistory.CommandResponse.CallHistoryRecentsResult.Entry);
|
||||
}
|
||||
else if (response.IndexOf("\"CallHistoryDeleteEntryResult\":{") > -1)
|
||||
}
|
||||
else if (response.IndexOf("\"CallHistoryDeleteEntryResult\":{") > -1 || response.IndexOf("\"CallHistoryDeleteEntryResult\": {") > -1)
|
||||
{
|
||||
GetCallHistory();
|
||||
}
|
||||
else if (response.IndexOf("\"PhonebookSearchResult\":{") > -1)
|
||||
}
|
||||
else if (response.IndexOf("\"PhonebookSearchResult\":{") > -1 || response.IndexOf("\"PhonebookSearchResult\": {") > -1)
|
||||
{
|
||||
var codecPhonebookResponse = new CiscoCodecPhonebook.RootObject();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user