Merge pull request #494 from PepperDash/release/1.6.7

Release/1.6.7
This commit is contained in:
Neil Dorin 2020-11-16 12:01:01 -07:00 committed by GitHub
commit ce86255119
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 6515 additions and 4927 deletions

View file

@ -32,7 +32,6 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
submodules: true
# Fetch all tags # Fetch all tags
- name: Fetch tags - name: Fetch tags
run: git fetch --tags run: git fetch --tags
@ -41,12 +40,11 @@ jobs:
shell: powershell shell: powershell
run: | run: |
$version = ./.github/scripts/GenerateVersionNumber.ps1 $version = ./.github/scripts/GenerateVersionNumber.ps1
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Use the version number to set the version of the assemblies # Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs - name: Update AssemblyInfo.cs
shell: powershell shell: powershell
run: | run: |
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }} ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- name: restore Nuget Packages - name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
@ -123,7 +121,7 @@ jobs:
Get-ChildItem "./Version" Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt $version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version" Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version Remove-Item -Path ./Version
- name: Download Build output - name: Download Build output
@ -180,7 +178,7 @@ jobs:
Get-ChildItem "./Version" Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt $version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version" Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version Remove-Item -Path ./Version
# Checkout/Create the branch # Checkout/Create the branch
@ -259,7 +257,7 @@ jobs:
Get-ChildItem "./Version" Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt $version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version" Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version Remove-Item -Path ./Version
# Checkout/Create the branch # Checkout/Create the branch

View file

@ -24,25 +24,18 @@ jobs:
# First we checkout the source repo # First we checkout the source repo
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@v2 uses: actions/checkout@v2
# And any submodules with:
- name: Checkout submodules fetch-depth: 0
shell: bash
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
# Generate the appropriate version number # Generate the appropriate version number
- name: Set Version Number - name: Set Version Number
shell: powershell shell: powershell
env: env:
TAG_NAME: ${{ github.event.release.tag_name }} TAG_NAME: ${{ github.event.release.tag_name }}
run: Write-Output "::set-env name=VERSION::$($Env:TAG_NAME)" run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Use the version number to set the version of the assemblies # Use the version number to set the version of the assemblies
- name: Update AssemblyInfo.cs - name: Update AssemblyInfo.cs
shell: powershell shell: powershell
run: | run: |
Write-Output ${{ env.VERSION }}
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }} ./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
- name: restore Nuget Packages - name: restore Nuget Packages
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
@ -101,7 +94,7 @@ jobs:
Get-ChildItem "./Version" Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt $version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version" Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version Remove-Item -Path ./Version
- name: Download Build output - name: Download Build output
@ -155,7 +148,7 @@ jobs:
Get-ChildItem "./Version" Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt $version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version" Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version Remove-Item -Path ./Version
# Checkout/Create the branch # Checkout/Create the branch
@ -228,7 +221,7 @@ jobs:
Get-ChildItem "./Version" Get-ChildItem "./Version"
$version = Get-Content -Path ./Version/version.txt $version = Get-Content -Path ./Version/version.txt
Write-Host "Version: $version" Write-Host "Version: $version"
Write-Output "::set-env name=VERSION::$version" echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Remove-Item -Path ./Version/version.txt Remove-Item -Path ./Version/version.txt
Remove-Item -Path ./Version Remove-Item -Path ./Version
# Checkout main branch # Checkout main branch

View file

@ -16,7 +16,6 @@ using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM; using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion; using PepperDash.Essentials.Fusion;
using PepperDash.Essentials.Room.Config; using PepperDash.Essentials.Room.Config;
//using PepperDash.Essentials.Room.MobileControl;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.DeviceTypeInterfaces;
@ -290,33 +289,14 @@ namespace PepperDash.Essentials
DeviceManager.ActivateAll(); DeviceManager.ActivateAll();
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl; var mobileControl = GetMobileControlDevice();
if (mobileControl == null) return; if (mobileControl == null) return;
mobileControl.LinkSystemMonitorToAppServer(); mobileControl.LinkSystemMonitorToAppServer();
//LinkSystemMonitorToAppServer();
} }
//void LinkSystemMonitorToAppServer()
//{
// var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
// var appServer = DeviceManager.GetDeviceForKey("appServer") as MobileControlSystemController;
// if (sysMon != null && appServer != null)
// {
// var key = sysMon.Key + "-" + appServer.Key;
// var messenger = new PepperDash.Essentials.AppServer.Messengers.SystemMonitorMessenger
// (key, sysMon, "/device/systemMonitor");
// messenger.RegisterWithAppServer(appServer);
// DeviceManager.AddDevice(messenger);
// }
//}
/// <summary> /// <summary>
/// Reads all devices from config and adds them to DeviceManager /// Reads all devices from config and adds them to DeviceManager
/// </summary> /// </summary>
@ -394,11 +374,6 @@ namespace PepperDash.Essentials
if (newDev == null) if (newDev == null)
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
//
//if (newDev == null)
// newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
//
if (newDev != null) if (newDev != null)
DeviceManager.AddDevice(newDev); DeviceManager.AddDevice(newDev);
else else
@ -465,10 +440,6 @@ namespace PepperDash.Essentials
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
// Mobile Control bridge
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
//DeviceManager.AddDevice(bridge);
CreateMobileControlBridge(room); CreateMobileControlBridge(room);
} }
@ -480,10 +451,6 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1)); DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
// Mobile Control bridge
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
//DeviceManager.AddDevice(bridge);
CreateMobileControlBridge(room); CreateMobileControlBridge(room);
} }
@ -504,34 +471,35 @@ namespace PepperDash.Essentials
private static void CreateMobileControlBridge(EssentialsRoomBase room) private static void CreateMobileControlBridge(EssentialsRoomBase room)
{ {
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl; var mobileControl = GetMobileControlDevice();
if (mobileControl == null) return; if (mobileControl == null) return;
mobileControl.CreateMobileControlRoomBridge(room); mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added..."); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
} }
/// <summary> private static IMobileControl GetMobileControlDevice()
/// Helps add the post activation steps that link bridges to main controller {
/// </summary> var mobileControlList = DeviceManager.AllDevices.OfType<IMobileControl>().ToList();
/// <param name="bridge"></param>
//void AddBridgePostActivationHelper(MobileControlBridgeBase bridge) if (mobileControlList.Count > 1)
//{ {
// bridge.AddPostActivationAction(() => Debug.Console(0, Debug.ErrorLogLevel.Warning,
// { "Multiple instances of Mobile Control Server found.");
// var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
// if (parent == null) return null;
// { }
// Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present");
// return; if (mobileControlList.Count > 0)
// } {
// Debug.Console(0, bridge, "Linking to parent controller"); return mobileControlList[0];
// bridge.AddParent(parent); }
// parent.AddBridge(bridge);
// }); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control not enabled for this system");
//} return null;
}
/// <summary> /// <summary>
/// Fires up a logo server if not already running /// Fires up a logo server if not already running

View file

@ -273,15 +273,18 @@ namespace PepperDash.Essentials.Fusion
// Display to fusion room sigs // Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
var defaultDisplayTwoWay = defaultDisplay as IHasPowerControlWithFeedback;
if (defaultDisplayTwoWay != null)
{
defaultDisplayTwoWay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
}
if (defaultDisplay is IDisplayUsage) if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
MapDisplayToRoomJoins(1, 158, defaultDisplay); MapDisplayToRoomJoins(1, 158, defaultDisplay);
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection //Check for existing asset in GUIDs collection
@ -302,8 +305,18 @@ namespace PepperDash.Essentials.Fusion
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
if (defaultTwoWayDisplay != null)
{
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
if (defaultDisplay is IDisplayUsage)
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
}
// Use extension methods // Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay); dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay); dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
@ -325,12 +338,17 @@ namespace PepperDash.Essentials.Fusion
// Power on // Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); }); defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Power Off // Power Off
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig); var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ; defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
var displayTwoWay = display as IHasPowerControlWithFeedback;
if (displayTwoWay != null)
{
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
}
// Current Source // Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);

View file

@ -71,7 +71,7 @@
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath> <HintPath>..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
</Reference> </Reference>

View file

@ -283,19 +283,23 @@ namespace PepperDash.Essentials
if (disp != null) if (disp != null)
{ {
// Link power, warming, cooling to display // Link power, warming, cooling to display
disp.PowerIsOnFeedback.OutputChange += (o, a) => var dispTwoWay = disp as IHasPowerControlWithFeedback;
{ if (dispTwoWay != null)
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) {
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
{ {
if (!disp.PowerIsOnFeedback.BoolValue) if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
disp.CurrentSourceInfo = null; {
OnFeedback.FireUpdate(); if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
} disp.CurrentSourceInfo = null;
if (disp.PowerIsOnFeedback.BoolValue) OnFeedback.FireUpdate();
{ }
SetDefaultLevels(); if (dispTwoWay.PowerIsOnFeedback.BoolValue)
} {
}; SetDefaultLevels();
}
};
}
disp.IsWarmingUpFeedback.OutputChange += (o, a) => disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{ {
@ -579,8 +583,8 @@ namespace PepperDash.Essentials
if (dest is IPower) if (dest is IHasPowerControl)
(dest as IPower).PowerOff(); (dest as IHasPowerControl).PowerOff();
} }
else else
{ {

View file

@ -176,15 +176,19 @@ namespace PepperDash.Essentials
if (disp != null) if (disp != null)
{ {
// Link power, warming, cooling to display // Link power, warming, cooling to display
disp.PowerIsOnFeedback.OutputChange += (o, a) => var dispTwoWay = disp as IHasPowerControlWithFeedback;
{ if (dispTwoWay != null)
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) {
{ dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
if (!disp.PowerIsOnFeedback.BoolValue) {
CurrentSourceInfo = null; if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
OnFeedback.FireUpdate(); {
} if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
}; CurrentSourceInfo = null;
OnFeedback.FireUpdate();
}
};
}
disp.IsWarmingUpFeedback.OutputChange += (o, a) => disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{ {
@ -495,8 +499,8 @@ namespace PepperDash.Essentials
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase)) if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{ {
dest.ReleaseRoute(); dest.ReleaseRoute();
if (dest is IPower) if (dest is IHasPowerControl)
(dest as IPower).PowerOff(); (dest as IHasPowerControl).PowerOff();
} }
else else
{ {

View file

@ -190,6 +190,12 @@ namespace PepperDash.Essentials
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control"); (_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
if (handler != null) if (handler != null)
handler(_CurrentSourceInfo, ChangeType.DidChange); handler(_CurrentSourceInfo, ChangeType.DidChange);
var vc = VideoCodec as IHasExternalSourceSwitching;
if (vc != null)
{
vc.SetSelectedSource(CurrentSourceInfoKey);
}
} }
} }
SourceListItem _CurrentSourceInfo; SourceListItem _CurrentSourceInfo;
@ -273,19 +279,23 @@ namespace PepperDash.Essentials
if (disp != null) if (disp != null)
{ {
// Link power, warming, cooling to display // Link power, warming, cooling to display
disp.PowerIsOnFeedback.OutputChange += (o, a) => var dispTwoWay = disp as IHasPowerControlWithFeedback;
{ if (dispTwoWay != null)
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue) {
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
{ {
if (!disp.PowerIsOnFeedback.BoolValue) if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
CurrentSourceInfo = null; {
OnFeedback.FireUpdate(); if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
} CurrentSourceInfo = null;
if (disp.PowerIsOnFeedback.BoolValue) OnFeedback.FireUpdate();
{ }
SetDefaultLevels(); if (dispTwoWay.PowerIsOnFeedback.BoolValue)
} {
}; SetDefaultLevels();
}
};
}
disp.IsWarmingUpFeedback.OutputChange += (o, a) => disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
{ {
@ -383,6 +393,8 @@ namespace PepperDash.Essentials
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room"); Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
RunRouteAction("roomOff"); RunRouteAction("roomOff");
VideoCodec.StopSharing();
VideoCodec.StandbyActivate();
} }
/// <summary> /// <summary>
@ -580,6 +592,19 @@ namespace PepperDash.Essentials
OnFeedback.FireUpdate(); OnFeedback.FireUpdate();
if (OnFeedback.BoolValue)
{
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
{
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
}
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
{
VideoCodec.StandbyDeactivate();
}
}
// report back when done // report back when done
if (successCallback != null) if (successCallback != null)
successCallback(); successCallback();
@ -640,8 +665,9 @@ namespace PepperDash.Essentials
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase)) if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{ {
dest.ReleaseRoute(); dest.ReleaseRoute();
if (dest is IPower) if (dest is IHasPowerControl)
(dest as IPower).PowerOff(); (dest as IHasPowerControl).PowerOff();
} }
else else
{ {
@ -693,37 +719,44 @@ namespace PepperDash.Essentials
} }
/// <summary> /// <summary>
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch /// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
/// </summary> /// </summary>
private void SetCodecExternalSources() private void SetCodecExternalSources()
{ {
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching; var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
if (videoCodecWithExternalSwitching == null) if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
{ {
return; return;
} }
string codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort; try
videoCodecWithExternalSwitching.ClearExternalSources(); {
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction; // Get the tie line that the external switcher is connected to
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ; string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
foreach (var kvp in srcList) videoCodecWithExternalSwitching.ClearExternalSources();
{ videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
var srcConfig = kvp.Value; var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff") foreach (var kvp in srcList)
{ {
var srcConfig = kvp.Value;
videoCodecWithExternalSwitching.AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop); if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready); {
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
} }
} }
} }
catch (Exception e)
{
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
}
}
private void SetCodecBranding() private void SetCodecBranding()
{ {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,11 +8,9 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
/// </summary> /// </summary>
public interface IMobileControl : IKeyed public interface IMobileControl : IKeyed
{ {
void CreateMobileControlRoomBridge(EssentialsRoomBase room); void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
void LinkSystemMonitorToAppServer(); void LinkSystemMonitorToAppServer();
} }
/// <summary> /// <summary>
@ -26,6 +24,8 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
string QrCodeUrl { get; } string QrCodeUrl { get; }
string QrCodeChecksum { get; }
string McServerUrl { get; } string McServerUrl { get; }
string RoomName { get; } string RoomName { get; }

View file

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

View file

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

View file

@ -20,10 +20,12 @@ namespace PepperDash.Essentials.Core
public IrOutputPortController IrPort { get; private set; } public IrOutputPortController IrPort { get; private set; }
public ushort IrPulseTime { get; set; } public ushort IrPulseTime { get; set; }
protected override Func<bool> PowerIsOnFeedbackFunc public BoolFeedback PowerIsOnFeedback { get; private set; }
{
get { return () => _PowerIsOn; } protected Func<bool> PowerIsOnFeedbackFunc
} {
get { return () => _PowerIsOn; }
}
protected override Func<bool> IsCoolingDownFeedbackFunc protected override Func<bool> IsCoolingDownFeedbackFunc
{ {
get { return () => _IsCoolingDown; } get { return () => _IsCoolingDown; }
@ -33,7 +35,7 @@ namespace PepperDash.Essentials.Core
get { return () => _IsWarmingUp; } get { return () => _IsWarmingUp; }
} }
bool _PowerIsOn; bool _PowerIsOn;
bool _IsWarmingUp; bool _IsWarmingUp;
bool _IsCoolingDown; bool _IsCoolingDown;
@ -43,11 +45,14 @@ namespace PepperDash.Essentials.Core
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath); IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
DeviceManager.AddDevice(IrPort); DeviceManager.AddDevice(IrPort);
PowerIsOnFeedback.OutputChange += (o, a) => { PowerIsOnFeedback = new BoolFeedback(PowerIsOnFeedbackFunc);
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
if (_PowerIsOn) StartWarmingTimer(); PowerIsOnFeedback.OutputChange += (o, a) =>
else StartCoolingTimer(); {
}; 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); IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown); IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
@ -110,21 +115,21 @@ namespace PepperDash.Essentials.Core
public override void PowerOn() public override void PowerOn()
{ {
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime); IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
_PowerIsOn = true; _PowerIsOn = true;
PowerIsOnFeedback.FireUpdate(); PowerIsOnFeedback.FireUpdate();
} }
public override void PowerOff() public override void PowerOff()
{ {
_PowerIsOn = false; _PowerIsOn = false;
PowerIsOnFeedback.FireUpdate(); PowerIsOnFeedback.FireUpdate();
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime); IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
} }
public override void PowerToggle() public override void PowerToggle()
{ {
_PowerIsOn = false; _PowerIsOn = false;
PowerIsOnFeedback.FireUpdate(); PowerIsOnFeedback.FireUpdate();
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime); IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
} }

View file

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

View file

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

View file

@ -83,7 +83,7 @@
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath> <HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
</Reference> </Reference>
@ -183,6 +183,9 @@
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" /> <Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" /> <Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
<Compile Include="Crestron IO\StatusSign\StatusSignController.cs" /> <Compile Include="Crestron IO\StatusSign\StatusSignController.cs" />
<Compile Include="Device Info\DeviceInfo.cs" />
<Compile Include="Device Info\DeviceInfoEventArgs.cs" />
<Compile Include="Device Info\IDeviceInfoProvider.cs" />
<Compile Include="Devices\CodecInterfaces.cs" /> <Compile Include="Devices\CodecInterfaces.cs" />
<Compile Include="Devices\CrestronProcessor.cs" /> <Compile Include="Devices\CrestronProcessor.cs" />
<Compile Include="Devices\DeviceApiBase.cs" /> <Compile Include="Devices\DeviceApiBase.cs" />

View file

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

View file

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

View file

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

View file

@ -17,7 +17,7 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM.AirMedia namespace PepperDash.Essentials.DM.AirMedia
{ {
[Description("Wrapper class for an AM-200 or AM-300")] [Description("Wrapper class for an AM-200 or AM-300")]
public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingNumeric, IIROutputPorts, IComPorts public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IIROutputPorts, IComPorts
{ {
public AmX00 AirMedia { get; private set; } public AmX00 AirMedia { get; private set; }
@ -29,6 +29,10 @@ namespace PepperDash.Essentials.DM.AirMedia
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; } public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
public BoolFeedback IsInSessionFeedback { get; private set; } public BoolFeedback IsInSessionFeedback { get; private set; }
public IntFeedback ErrorFeedback { get; private set; } public IntFeedback ErrorFeedback { get; private set; }
public IntFeedback NumberOfUsersConnectedFeedback { get; set; } public IntFeedback NumberOfUsersConnectedFeedback { get; set; }
@ -43,6 +47,7 @@ namespace PepperDash.Essentials.DM.AirMedia
public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props) public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props)
: base(key, name, device) : base(key, name, device)
{ {
AirMedia = device; AirMedia = device;
DeviceConfig = dc; DeviceConfig = dc;
@ -53,21 +58,36 @@ namespace PepperDash.Essentials.DM.AirMedia
OutputPorts = new RoutingPortCollection<RoutingOutputPort>(); OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.AudioVideo, InputPorts.Add(new RoutingInputPort(DmPortName.Osd, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this)); eRoutingPortConnectionType.None, new Action(SelectPinPointUxLandingPage), this)
{
FeedbackMatchObject = 0
});
InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.AudioVideo, InputPorts.Add(new RoutingInputPort(DmPortName.AirMediaIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this)); eRoutingPortConnectionType.Streaming, new Action(SelectAirMedia), this)
{
FeedbackMatchObject = 1
});
InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.AudioVideo, InputPorts.Add(new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this)); eRoutingPortConnectionType.Hdmi, new Action(SelectHdmiIn), this)
{
FeedbackMatchObject = 2
});
InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.AudioVideo, InputPorts.Add(new RoutingInputPort(DmPortName.AirBoardIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this)); eRoutingPortConnectionType.None, new Action(SelectAirboardIn), this)
{
FeedbackMatchObject = 4
});
if (AirMedia is Am300) if (AirMedia is Am300)
{ {
InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo, InputPorts.Add(new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this)); eRoutingPortConnectionType.DmCat, new Action(SelectDmIn), this)
{
FeedbackMatchObject = 3
});
} }
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo, OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
@ -153,6 +173,17 @@ namespace PepperDash.Essentials.DM.AirMedia
SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumberFeedback.JoinNumber]); SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumberFeedback.JoinNumber]);
} }
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
void AirMedia_AirMediaChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args) void AirMedia_AirMediaChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{ {
if (args.EventId == AirMediaInputSlot.AirMediaStatusFeedbackEventId) if (args.EventId == AirMediaInputSlot.AirMediaStatusFeedbackEventId)
@ -172,12 +203,20 @@ namespace PepperDash.Essentials.DM.AirMedia
void DisplayControl_DisplayControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args) void DisplayControl_DisplayControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{ {
if (args.EventId == AmX00.VideoOutFeedbackEventId) if (args.EventId == AmX00.VideoOutFeedbackEventId)
{
VideoOutFeedback.FireUpdate(); VideoOutFeedback.FireUpdate();
var localInputPort =
InputPorts.FirstOrDefault(p => (int) p.FeedbackMatchObject == VideoOutFeedback.UShortValue);
OnSwitchChange(new RoutingNumericEventArgs(1, VideoOutFeedback.UShortValue, OutputPorts.First(),
localInputPort, eRoutingSignalType.AudioVideo));
}
else if (args.EventId == AmX00.EnableAutomaticRoutingFeedbackEventId) else if (args.EventId == AmX00.EnableAutomaticRoutingFeedbackEventId)
AutomaticInputRoutingEnabledFeedback.FireUpdate(); AutomaticInputRoutingEnabledFeedback.FireUpdate();
} }
void HdmiIn_StreamChange(Crestron.SimplSharpPro.DeviceSupport.Stream stream, Crestron.SimplSharpPro.DeviceSupport.StreamEventArgs args) void HdmiIn_StreamChange(Stream stream, Crestron.SimplSharpPro.DeviceSupport.StreamEventArgs args)
{ {
if (args.EventId == DMInputEventIds.SourceSyncEventId) if (args.EventId == DMInputEventIds.SourceSyncEventId)
HdmiVideoSyncDetectedFeedback.FireUpdate(); HdmiVideoSyncDetectedFeedback.FireUpdate();

View file

@ -21,12 +21,15 @@ namespace PepperDash.Essentials.DM {
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
/// ///
/// </summary> /// </summary>
public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumeric public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback
{ {
public DMChassisPropertiesConfig PropertiesConfig { get; set; } public DMChassisPropertiesConfig PropertiesConfig { get; set; }
public Switch Chassis { get; private set; } public Switch Chassis { get; private set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
// Feedbacks for EssentialDM // Feedbacks for EssentialDM
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; } public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; } public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; }
@ -287,6 +290,15 @@ namespace PepperDash.Essentials.DM {
} }
} }
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
void AddHdmiInBladePorts(uint number, ICec cecPort) { void AddHdmiInBladePorts(uint number, ICec cecPort) {
@ -377,7 +389,10 @@ namespace PepperDash.Essentials.DM {
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) { void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) {
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey); Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
};
InputPorts.Add(inputPort); InputPorts.Add(inputPort);
} }
@ -385,19 +400,20 @@ namespace PepperDash.Essentials.DM {
/// <summary> /// <summary>
/// Adds InputPort and sets Port as ICec object /// Adds InputPort and sets Port as ICec object
/// </summary> /// </summary>
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort) { private void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType,
eRoutingPortConnectionType portType, ICec cecPort)
{
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey); Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
};
if (inputPort != null) { if (cecPort != null)
if (cecPort != null) inputPort.Port = cecPort;
inputPort.Port = cecPort;
InputPorts.Add(inputPort); InputPorts.Add(inputPort);
}
else
Debug.Console(2, this, "inputPort is null");
} }
@ -407,7 +423,10 @@ namespace PepperDash.Essentials.DM {
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) { void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) {
var portKey = string.Format("{0}--{1}", cardName, portName); var portKey = string.Format("{0}--{1}", cardName, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey); Debug.Console(2, this, "Adding output port '{0}'", portKey);
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)); OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
{
FeedbackMatchObject = Chassis.Outputs[(uint)selector]
});
} }
@ -458,54 +477,84 @@ namespace PepperDash.Essentials.DM {
} }
} }
} }
/// ///
/// </summary> /// </summary>
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) private void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
{ {
var output = args.Number; var output = args.Number;
switch (args.EventId) { switch (args.EventId)
case DMOutputEventIds.VolumeEventId: { {
if (VolumeControls.ContainsKey(output)) { case DMOutputEventIds.VolumeEventId:
VolumeControls[args.Number].VolumeEventFromChassis(); {
} if (VolumeControls.ContainsKey(output))
break; {
VolumeControls[args.Number].VolumeEventFromChassis();
} }
case DMOutputEventIds.EndpointOnlineEventId: { break;
Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); }
if(Chassis.Outputs[output].Endpoint != null) case DMOutputEventIds.EndpointOnlineEventId:
Debug.Console(2, this, "Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}", args.Number, Chassis.Outputs[output].Endpoint.IsOnline); {
Debug.Console(2, this,
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. EndpointOnlineFeedback State: {1}",
args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
if (Chassis.Outputs[output].Endpoint != null)
Debug.Console(2, this,
"Output {0} DMOutputEventIds.EndpointOnlineEventId fired. Endpoint.IsOnline State: {1}",
args.Number, Chassis.Outputs[output].Endpoint.IsOnline);
OutputEndpointOnlineFeedbacks[output].FireUpdate(); OutputEndpointOnlineFeedbacks[output].FireUpdate();
break; break;
} }
case DMOutputEventIds.OnlineFeedbackEventId: { case DMOutputEventIds.OnlineFeedbackEventId:
Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}", args.Number, Chassis.Outputs[output].EndpointOnlineFeedback); {
OutputEndpointOnlineFeedbacks[output].FireUpdate(); Debug.Console(2, this, "Output {0} DMInputEventIds.OnlineFeedbackEventId fired. State: {1}",
break; args.Number, Chassis.Outputs[output].EndpointOnlineFeedback);
} OutputEndpointOnlineFeedbacks[output].FireUpdate();
case DMOutputEventIds.VideoOutEventId: { break;
if (Chassis.Outputs[output].VideoOutFeedback != null) { }
Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].VideoOutFeedback.Number, output); case DMOutputEventIds.VideoOutEventId:
} {
if (VideoOutputFeedbacks.ContainsKey(output)) {
VideoOutputFeedbacks[output].FireUpdate(); var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.Outputs[output].VideoOutFeedback.Number;
Debug.Console(2, this, "DMSwitchAudioVideo:{0} Routed Input:{1} Output:{2}'", this.Name,
inputNumber, output);
if (VideoOutputFeedbacks.ContainsKey(output))
{
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
var localOutputPort =
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
VideoOutputFeedbacks[output].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output,
inputNumber,
localOutputPort,
localInputPort,
eRoutingSignalType.AudioVideo));
}
if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) {
OutputVideoRouteNameFeedbacks[output].FireUpdate();
}
break;
} }
case DMOutputEventIds.OutputNameEventId: { if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output); {
OutputNameFeedbacks[output].FireUpdate(); OutputVideoRouteNameFeedbacks[output].FireUpdate();
break;
}
default: {
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}", args.Number, args.EventId);
break;
} }
break;
}
case DMOutputEventIds.OutputNameEventId:
{
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
OutputNameFeedbacks[output].FireUpdate();
break;
}
default:
{
Debug.Console(2, this, "DMOutputChange fired for Output {0} with Unhandled EventId: {1}",
args.Number, args.EventId);
break;
}
} }
} }

View file

@ -20,12 +20,15 @@ namespace PepperDash.Essentials.DM
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
/// ///
/// </summary> /// </summary>
[Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")] [Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")]
public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumeric public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback
{ {
public DMChassisPropertiesConfig PropertiesConfig { get; set; } public DMChassisPropertiesConfig PropertiesConfig { get; set; }
public Switch Chassis { get; private set; } public Switch Chassis { get; private set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
// Feedbacks for EssentialDM // Feedbacks for EssentialDM
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; } public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
@ -187,7 +190,8 @@ namespace PepperDash.Essentials.DM
/// <param name="chassis"></param> /// <param name="chassis"></param>
public DmChassisController(string key, string name, DmMDMnxn chassis) public DmChassisController(string key, string name, DmMDMnxn chassis)
: base(key, name, chassis) : base(key, name, chassis)
{ {
Chassis = chassis; Chassis = chassis;
InputPorts = new RoutingPortCollection<RoutingInputPort>(); InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>(); OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
@ -737,7 +741,10 @@ namespace PepperDash.Essentials.DM
{ {
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey); Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
};
InputPorts.Add(inputPort); InputPorts.Add(inputPort);
} }
@ -749,12 +756,15 @@ namespace PepperDash.Essentials.DM
{ {
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey); Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
}; ;
if (cecPort != null) if (cecPort != null)
inputPort.Port = cecPort; inputPort.Port = cecPort;
InputPorts.Add(inputPort); InputPorts.Add(inputPort);
} }
/// <summary> /// <summary>
@ -763,8 +773,16 @@ namespace PepperDash.Essentials.DM
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector) void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector)
{ {
var portKey = string.Format("{0}--{1}", cardName, portName); var portKey = string.Format("{0}--{1}", cardName, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey); Debug.Console(2, this, "Adding output port '{0}'", portKey);
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this));
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this);
if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0)
{
outputPort.FeedbackMatchObject = Chassis.Outputs[(uint) selector];
}
OutputPorts.Add(outputPort);
} }
/// <summary> /// <summary>
@ -773,13 +791,17 @@ namespace PepperDash.Essentials.DM
void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort) void AddOutputPortWithDebug(string cardName, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, object selector, ICec cecPort)
{ {
var portKey = string.Format("{0}--{1}", cardName, portName); var portKey = string.Format("{0}--{1}", cardName, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey); Debug.Console(2, this, "Adding output port '{0}'", portKey);
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this);
if (portName.IndexOf("Loop", StringComparison.InvariantCultureIgnoreCase) < 0)
{
outputPort.FeedbackMatchObject = Chassis.Outputs[(uint)selector];
}
if (cecPort != null) if (cecPort != null)
outputPort.Port = cecPort; outputPort.Port = cecPort;
OutputPorts.Add(outputPort); OutputPorts.Add(outputPort);
} }
/// <summary> /// <summary>
@ -905,6 +927,17 @@ namespace PepperDash.Essentials.DM
{ {
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Chassis_DMInputChange: {0}", ex); Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Chassis_DMInputChange: {0}", ex);
} }
}
/// <summary>
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
} }
/// ///
@ -938,30 +971,59 @@ namespace PepperDash.Essentials.DM
OutputEndpointOnlineFeedbacks[output].FireUpdate(); OutputEndpointOnlineFeedbacks[output].FireUpdate();
break; break;
} }
case DMOutputEventIds.VideoOutEventId: case DMOutputEventIds.VideoOutEventId:
{ {
if (Chassis.Outputs[output].VideoOutFeedback != null)
Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].VideoOutFeedback.Number, output); var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.
Outputs[output].VideoOutFeedback.Number;
if (VideoOutputFeedbacks.ContainsKey(output))
VideoOutputFeedbacks[output].FireUpdate(); Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output);
if (VideoOutputFeedbacks.ContainsKey(output))
{
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].VideoOutFeedback);
var localOutputPort =
OutputPorts.FirstOrDefault(p => (DMOutput) p.FeedbackMatchObject == Chassis.Outputs[output]);
VideoOutputFeedbacks[output].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output,
inputNumber,
localOutputPort,
localInputPort,
eRoutingSignalType.Video));
}
if (OutputVideoRouteNameFeedbacks.ContainsKey(output)) if (OutputVideoRouteNameFeedbacks.ContainsKey(output))
OutputVideoRouteNameFeedbacks[output].FireUpdate(); OutputVideoRouteNameFeedbacks[output].FireUpdate();
break; break;
} }
case DMOutputEventIds.AudioOutEventId: case DMOutputEventIds.AudioOutEventId:
{ {
if (Chassis.Outputs[output].AudioOutFeedback != null) var inputNumber = Chassis.Outputs[output].AudioOutFeedback == null ? 0 : Chassis.
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Chassis.Outputs[output].AudioOutFeedback.Number, output); Outputs[output].AudioOutFeedback.Number;
if (AudioOutputFeedbacks.ContainsKey(output)) Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output);
AudioOutputFeedbacks[output].FireUpdate();
if (AudioOutputFeedbacks.ContainsKey(output))
if (OutputAudioRouteNameFeedbacks.ContainsKey(output)) {
OutputAudioRouteNameFeedbacks[output].FireUpdate(); var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == Chassis.Outputs[output].AudioOutFeedback);
var localOutputPort =
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == Chassis.Outputs[output]);
AudioOutputFeedbacks[output].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output,
inputNumber,
localOutputPort,
localInputPort,
eRoutingSignalType.Audio));
}
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
OutputAudioRouteNameFeedbacks[output].FireUpdate();
break; break;
} }
case DMOutputEventIds.OutputNameEventId: case DMOutputEventIds.OutputNameEventId:

View file

@ -18,12 +18,15 @@ using PepperDash.Essentials.DM.Config;
using Feedback = PepperDash.Essentials.Core.Feedback; using Feedback = PepperDash.Essentials.Core.Feedback;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
public class DmpsRoutingController : EssentialsBridgeableDevice, IRoutingNumeric, IHasFeedback public class DmpsRoutingController : EssentialsBridgeableDevice, IRoutingNumericWithFeedback, IHasFeedback
{ {
public CrestronControlSystem Dmps { get; set; } public CrestronControlSystem Dmps { get; set; }
public ISystemControl SystemControl { get; private set; } public ISystemControl SystemControl { get; private set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
// Feedbacks for EssentialDM // Feedbacks for EssentialDM
public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; } public Dictionary<uint, IntFeedback> VideoOutputFeedbacks { get; private set; }
public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; } public Dictionary<uint, IntFeedback> AudioOutputFeedbacks { get; private set; }
@ -56,11 +59,23 @@ namespace PepperDash.Essentials.DM
/// </summary> /// </summary>
public string NoRouteText = ""; public string NoRouteText = "";
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
public static DmpsRoutingController GetDmpsRoutingController(string key, string name, public static DmpsRoutingController GetDmpsRoutingController(string key, string name,
DmpsRoutingPropertiesConfig properties) DmpsRoutingPropertiesConfig properties)
{ {
try try
{ {
ISystemControl systemControl = null; ISystemControl systemControl = null;
systemControl = Global.ControlSystem.SystemControl as ISystemControl; systemControl = Global.ControlSystem.SystemControl as ISystemControl;
@ -118,8 +133,8 @@ namespace PepperDash.Essentials.DM
OutputEndpointOnlineFeedbacks = new Dictionary<uint, BoolFeedback>(); OutputEndpointOnlineFeedbacks = new Dictionary<uint, BoolFeedback>();
Debug.Console(1, this, "{0} Switcher Inputs Present.", Dmps.SwitcherInputs.Count); Debug.Console(1, this, "{0} Switcher Inputs Present.", Dmps.SwitcherInputs.Count);
Debug.Console(1, this, "{0} Switcher Outputs Present.", Dmps.SwitcherOutputs.Count); Debug.Console(1, this, "{0} Switcher Outputs Present.", Dmps.SwitcherOutputs.Count);
Debug.Console(1, this, "{0} Inputs in ControlSystem", Dmps.NumberOfSwitcherInputs); Debug.Console(1, this, "{0} Inputs in ControlSystem", Dmps.NumberOfSwitcherInputs);
Debug.Console(1, this, "{0} Outputs in ControlSystem", Dmps.NumberOfSwitcherOutputs); Debug.Console(1, this, "{0} Outputs in ControlSystem", Dmps.NumberOfSwitcherOutputs);
@ -140,57 +155,57 @@ namespace PepperDash.Essentials.DM
Dmps.DMOutputChange += Dmps_DMOutputChange; Dmps.DMOutputChange += Dmps_DMOutputChange;
return base.CustomActivate(); return base.CustomActivate();
} }
private void SetOutputNames() private void SetOutputNames()
{ {
if (OutputNames == null) if (OutputNames == null)
{ {
return; return;
} }
foreach (var kvp in OutputNames) foreach (var kvp in OutputNames)
{ {
var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput); var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput);
if (output != null && output.Name.Type != eSigType.NA) if (output != null && output.Name.Type != eSigType.NA)
{ {
output.Name.StringValue = kvp.Value; output.Name.StringValue = kvp.Value;
} }
} }
} }
private void SetInputNames() private void SetInputNames()
{ {
if (InputNames == null) if (InputNames == null)
{ {
return; return;
} }
foreach (var kvp in InputNames) foreach (var kvp in InputNames)
{ {
var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput); var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput);
if (input != null && input.Name.Type != eSigType.NA) if (input != null && input.Name.Type != eSigType.NA)
{ {
input.Name.StringValue = kvp.Value; input.Name.StringValue = kvp.Value;
} }
} }
} }
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{ {
var joinMap = new DmpsRoutingControllerJoinMap(joinStart); var joinMap = new DmpsRoutingControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey); var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized)) if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmpsRoutingControllerJoinMap>(joinMapSerialized); joinMap = JsonConvert.DeserializeObject<DmpsRoutingControllerJoinMap>(joinMapSerialized);
if (bridge != null) if (bridge != null)
{ {
bridge.AddJoinMap(Key, joinMap); bridge.AddJoinMap(Key, joinMap);
} }
else else
{ {
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device."); 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")); Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
@ -199,203 +214,203 @@ namespace PepperDash.Essentials.DM
LinkInputsToApi(trilist, joinMap); LinkInputsToApi(trilist, joinMap);
LinkOutputsToApi(trilist, joinMap); LinkOutputsToApi(trilist, joinMap);
} }
private void LinkOutputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap) private void LinkOutputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
{ {
for (uint i = 1; i <= Dmps.SwitcherOutputs.Count; i++) for (uint i = 1; i <= Dmps.SwitcherOutputs.Count; i++)
{ {
Debug.Console(2, this, "Linking Output Card {0}", i); Debug.Console(2, this, "Linking Output Card {0}", i);
var ioSlot = i; var ioSlot = i;
var ioSlotJoin = ioSlot - 1; var ioSlotJoin = ioSlot - 1;
// Control // Control
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin, trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + ioSlotJoin,
o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video)); o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Video));
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin, trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + ioSlotJoin,
o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio)); o => ExecuteSwitch(o, ioSlot, eRoutingSignalType.Audio));
trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s => trilist.SetStringSigAction(joinMap.OutputNames.JoinNumber + ioSlotJoin, s =>
{ {
var outputCard = Dmps.SwitcherOutputs[ioSlot] as DMOutput; var outputCard = Dmps.SwitcherOutputs[ioSlot] as DMOutput;
//Debug.Console(2, dmpsRouter, "Output Name String Sig Action for Output Card {0}", ioSlot); //Debug.Console(2, dmpsRouter, "Output Name String Sig Action for Output Card {0}", ioSlot);
if (outputCard == null) if (outputCard == null)
{ {
return; return;
} }
//Debug.Console(2, dmpsRouter, "Card Type: {0}", outputCard.CardInputOutputType); //Debug.Console(2, dmpsRouter, "Card Type: {0}", outputCard.CardInputOutputType);
if (outputCard is Card.Dmps3CodecOutput || outputCard.NameFeedback == null) if (outputCard is Card.Dmps3CodecOutput || outputCard.NameFeedback == null)
{ {
return; return;
} }
if (string.IsNullOrEmpty(outputCard.NameFeedback.StringValue)) if (string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
{ {
return; return;
} }
//Debug.Console(2, dmpsRouter, "NameFeedabck: {0}", outputCard.NameFeedback.StringValue); //Debug.Console(2, dmpsRouter, "NameFeedabck: {0}", outputCard.NameFeedback.StringValue);
if (outputCard.NameFeedback.StringValue != s && outputCard.Name != null) if (outputCard.NameFeedback.StringValue != s && outputCard.Name != null)
{ {
outputCard.Name.StringValue = s; outputCard.Name.StringValue = s;
} }
}); });
// Feedback // Feedback
if (VideoOutputFeedbacks[ioSlot] != null) if (VideoOutputFeedbacks[ioSlot] != null)
{ {
VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]); VideoOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputVideo.JoinNumber + ioSlotJoin]);
} }
if (AudioOutputFeedbacks[ioSlot] != null) if (AudioOutputFeedbacks[ioSlot] != null)
{ {
AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]); AudioOutputFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + ioSlotJoin]);
} }
if (OutputNameFeedbacks[ioSlot] != null) if (OutputNameFeedbacks[ioSlot] != null)
{ {
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
} }
if (OutputVideoRouteNameFeedbacks[ioSlot] != null) if (OutputVideoRouteNameFeedbacks[ioSlot] != null)
{ {
OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig( OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(
trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]); trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + ioSlotJoin]);
} }
if (OutputAudioRouteNameFeedbacks[ioSlot] != null) if (OutputAudioRouteNameFeedbacks[ioSlot] != null)
{ {
OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig( OutputAudioRouteNameFeedbacks[ioSlot].LinkInputSig(
trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]); trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + ioSlotJoin]);
} }
if (OutputEndpointOnlineFeedbacks[ioSlot] != null) if (OutputEndpointOnlineFeedbacks[ioSlot] != null)
{ {
OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( OutputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(
trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]); trilist.BooleanInput[joinMap.OutputEndpointOnline.JoinNumber + ioSlotJoin]);
} }
} }
} }
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap) private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
{ {
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++) for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
{ {
Debug.Console(2, this, "Linking Input Card {0}", i); Debug.Console(2, this, "Linking Input Card {0}", i);
var ioSlot = i; var ioSlot = i;
var ioSlotJoin = ioSlot - 1; var ioSlotJoin = ioSlot - 1;
if (VideoInputSyncFeedbacks[ioSlot] != null) if (VideoInputSyncFeedbacks[ioSlot] != null)
{ {
VideoInputSyncFeedbacks[ioSlot].LinkInputSig( VideoInputSyncFeedbacks[ioSlot].LinkInputSig(
trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]); trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + ioSlotJoin]);
} }
if (InputNameFeedbacks[ioSlot] != null) if (InputNameFeedbacks[ioSlot] != null)
{ {
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]);
} }
trilist.SetStringSigAction(joinMap.InputNames.JoinNumber + ioSlotJoin, s => trilist.SetStringSigAction(joinMap.InputNames.JoinNumber + ioSlotJoin, s =>
{ {
var inputCard = Dmps.SwitcherInputs[ioSlot] as DMInput; var inputCard = Dmps.SwitcherInputs[ioSlot] as DMInput;
if (inputCard == null) if (inputCard == null)
{ {
return; return;
} }
if (inputCard.NameFeedback == null || string.IsNullOrEmpty(inputCard.NameFeedback.StringValue) || if (inputCard.NameFeedback == null || string.IsNullOrEmpty(inputCard.NameFeedback.StringValue) ||
inputCard.NameFeedback.StringValue == s) inputCard.NameFeedback.StringValue == s)
{ {
return; return;
} }
if (inputCard.Name != null) if (inputCard.Name != null)
{ {
inputCard.Name.StringValue = s; inputCard.Name.StringValue = s;
} }
}); });
if (InputEndpointOnlineFeedbacks[ioSlot] != null) if (InputEndpointOnlineFeedbacks[ioSlot] != null)
{ {
InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig( InputEndpointOnlineFeedbacks[ioSlot].LinkInputSig(
trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]); trilist.BooleanInput[joinMap.InputEndpointOnline.JoinNumber + ioSlotJoin]);
} }
} }
} }
/// <summary> /// <summary>
/// Iterate the SwitcherOutputs collection to setup feedbacks and add routing ports /// Iterate the SwitcherOutputs collection to setup feedbacks and add routing ports
/// </summary> /// </summary>
void SetupOutputCards() void SetupOutputCards()
{ {
foreach (var card in Dmps.SwitcherOutputs) foreach (var card in Dmps.SwitcherOutputs)
{ {
Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType); Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType);
var outputCard = card as DMOutput; var outputCard = card as DMOutput;
if (outputCard == null) if (outputCard == null)
{ {
Debug.Console(1, this, "Output card {0} is not a DMOutput", card.CardInputOutputType); Debug.Console(1, this, "Output card {0} is not a DMOutput", card.CardInputOutputType);
continue; continue;
} }
Debug.Console(1, this, "Adding Output Card Number {0} Type: {1}", outputCard.Number, outputCard.CardInputOutputType.ToString()); Debug.Console(1, this, "Adding Output Card Number {0} Type: {1}", outputCard.Number, outputCard.CardInputOutputType.ToString());
VideoOutputFeedbacks[outputCard.Number] = new IntFeedback(() => VideoOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{ {
if (outputCard.VideoOutFeedback != null) { return (ushort)outputCard.VideoOutFeedback.Number; } if (outputCard.VideoOutFeedback != null) { return (ushort)outputCard.VideoOutFeedback.Number; }
return 0; return 0;
; ;
}); });
AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() => AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{ {
try try
{ {
if (outputCard.AudioOutFeedback != null) if (outputCard.AudioOutFeedback != null)
{ {
return (ushort) outputCard.AudioOutFeedback.Number; return (ushort) outputCard.AudioOutFeedback.Number;
} }
return 0; return 0;
} }
catch (NotSupportedException) catch (NotSupportedException)
{ {
return (ushort) outputCard.AudioOutSourceFeedback; return (ushort) outputCard.AudioOutSourceFeedback;
} }
}); });
OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() => OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{ {
if (outputCard.NameFeedback != null && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue)) if (outputCard.NameFeedback != null && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
{ {
Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue); Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue);
return outputCard.NameFeedback.StringValue; return outputCard.NameFeedback.StringValue;
} }
return ""; return "";
}); });
OutputVideoRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() => OutputVideoRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{ {
if (outputCard.VideoOutFeedback != null && outputCard.VideoOutFeedback.NameFeedback != null) if (outputCard.VideoOutFeedback != null && outputCard.VideoOutFeedback.NameFeedback != null)
{ {
return outputCard.VideoOutFeedback.NameFeedback.StringValue; return outputCard.VideoOutFeedback.NameFeedback.StringValue;
} }
return NoRouteText; return NoRouteText;
}); });
OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() => OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{ {
if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null) if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null)
{ {
return outputCard.AudioOutFeedback.NameFeedback.StringValue; return outputCard.AudioOutFeedback.NameFeedback.StringValue;
} }
return NoRouteText; return NoRouteText;
}); });
OutputEndpointOnlineFeedbacks[outputCard.Number] = new BoolFeedback(() => outputCard.EndpointOnlineFeedback); OutputEndpointOnlineFeedbacks[outputCard.Number] = new BoolFeedback(() => outputCard.EndpointOnlineFeedback);
AddOutputCard(outputCard.Number, outputCard); AddOutputCard(outputCard.Number, outputCard);
} }
} }
@ -513,11 +528,16 @@ namespace PepperDash.Essentials.DM
/// <summary> /// <summary>
/// Adds InputPort /// Adds InputPort
/// </summary> /// </summary>
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType) private void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType,
eRoutingPortConnectionType portType)
{ {
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey); Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this)
{
FeedbackMatchObject = Dmps.SwitcherInputs[cardNum]
};
;
InputPorts.Add(inputPort); InputPorts.Add(inputPort);
} }
@ -529,7 +549,11 @@ namespace PepperDash.Essentials.DM
{ {
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName); var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey); Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this); var inputPort = new RoutingInputPort(portKey, sigType, portType, cardNum, this)
{
FeedbackMatchObject = Dmps.SwitcherInputs[cardNum]
};
;
if (cecPort != null) if (cecPort != null)
inputPort.Port = cecPort; inputPort.Port = cecPort;
@ -537,6 +561,7 @@ namespace PepperDash.Essentials.DM
InputPorts.Add(inputPort); InputPorts.Add(inputPort);
} }
/// <summary> /// <summary>
/// Builds the appropriate ports and calls the appropriate add port method /// Builds the appropriate ports and calls the appropriate add port method
/// </summary> /// </summary>
@ -550,23 +575,23 @@ namespace PepperDash.Essentials.DM
var cecPort = hdmiOutputCard.HdmiOutputPort; var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort); AddHdmiOutputPort(number, cecPort);
} }
else if (outputCard is Card.Dmps3HdmiOutputBackend) else if (outputCard is Card.Dmps3HdmiOutputBackend)
{ {
var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend; var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend;
var cecPort = hdmiOutputCard.HdmiOutputPort; var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort); AddHdmiOutputPort(number, cecPort);
} }
else if (outputCard is Card.Dmps3DmOutput) else if (outputCard is Card.Dmps3DmOutput)
{ {
AddDmOutputPort(number); AddDmOutputPort(number);
} }
else if (outputCard is Card.Dmps3DmOutputBackend) else if (outputCard is Card.Dmps3DmOutputBackend)
{ {
AddDmOutputPort(number); AddDmOutputPort(number);
} }
else if (outputCard is Card.Dmps3ProgramOutput) else if (outputCard is Card.Dmps3ProgramOutput)
{ {
@ -574,51 +599,51 @@ namespace PepperDash.Essentials.DM
var programOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); var programOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase);
DeviceManager.AddDevice(programOutput); DeviceManager.AddDevice(programOutput);
} }
else if (outputCard is Card.Dmps3AuxOutput) else if (outputCard is Card.Dmps3AuxOutput)
{ {
switch (outputCard.CardInputOutputType) switch (outputCard.CardInputOutputType)
{ {
case eCardInputOutputType.Dmps3Aux1Output: case eCardInputOutputType.Dmps3Aux1Output:
{ {
AddAudioOnlyOutputPort(number, "Aux1"); AddAudioOnlyOutputPort(number, "Aux1");
var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase);
DeviceManager.AddDevice(aux1Output); DeviceManager.AddDevice(aux1Output);
} }
break; break;
case eCardInputOutputType.Dmps3Aux2Output: case eCardInputOutputType.Dmps3Aux2Output:
{ {
AddAudioOnlyOutputPort(number, "Aux2"); AddAudioOnlyOutputPort(number, "Aux2");
var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase); var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3OutputBase);
DeviceManager.AddDevice(aux2Output); DeviceManager.AddDevice(aux2Output);
} }
break; break;
} }
} }
else if (outputCard is Card.Dmps3CodecOutput) else if (outputCard is Card.Dmps3CodecOutput)
{ {
switch (number) switch (number)
{ {
case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec1: case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec1:
case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec1: case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec1:
case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec1: case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec1:
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec1.ToString()); AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec1.ToString());
break; break;
case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec2: case (uint)CrestronControlSystem.eDmps34K350COutputs.Codec2:
case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec2: case (uint)CrestronControlSystem.eDmps34K250COutputs.Codec2:
case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec2: case (uint)CrestronControlSystem.eDmps3300cAecOutputs.Codec2:
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec2.ToString()); AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps300cOutputs.Codec2.ToString());
break; break;
} }
} }
else if (outputCard is Card.Dmps3DialerOutput) else if (outputCard is Card.Dmps3DialerOutput)
{ {
AddAudioOnlyOutputPort(number, "Dialer"); AddAudioOnlyOutputPort(number, "Dialer");
} }
else if (outputCard is Card.Dmps3DigitalMixOutput) else if (outputCard is Card.Dmps3DigitalMixOutput)
{ {
@ -629,11 +654,11 @@ namespace PepperDash.Essentials.DM
if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix2 if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix2
|| number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2 || number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2
|| number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2) || number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2)
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString()); AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString());
} }
else if (outputCard is Card.Dmps3AecOutput) else if (outputCard is Card.Dmps3AecOutput)
{ {
AddAudioOnlyOutputPort(number, "Aec"); AddAudioOnlyOutputPort(number, "Aec");
} }
else else
{ {
@ -676,7 +701,10 @@ namespace PepperDash.Essentials.DM
{ {
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName); var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey); Debug.Console(2, this, "Adding output port '{0}'", portKey);
OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)); OutputPorts.Add(new RoutingOutputPort(portKey, sigType, portType, selector, this)
{
FeedbackMatchObject = Dmps.SwitcherOutputs[cardNum]
});
} }
/// <summary> /// <summary>
@ -686,7 +714,10 @@ namespace PepperDash.Essentials.DM
{ {
var portKey = string.Format("outputCard{0}--{1}", cardNum, portName); var portKey = string.Format("outputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding output port '{0}'", portKey); Debug.Console(2, this, "Adding output port '{0}'", portKey);
var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this); var outputPort = new RoutingOutputPort(portKey, sigType, portType, selector, this)
{
FeedbackMatchObject = Dmps.SwitcherOutputs[cardNum]
};
if (cecPort != null) if (cecPort != null)
outputPort.Port = cecPort; outputPort.Port = cecPort;
@ -762,31 +793,31 @@ namespace PepperDash.Essentials.DM
} }
} }
else if (args.EventId == DMOutputEventIds.AudioOutEventId) else if (args.EventId == DMOutputEventIds.AudioOutEventId)
{ {
try try
{ {
if (outputCard != null && outputCard.AudioOutFeedback != null) if (outputCard != null && outputCard.AudioOutFeedback != null)
{ {
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name,
outputCard.AudioOutFeedback.Number, output); outputCard.AudioOutFeedback.Number, output);
} }
if (AudioOutputFeedbacks.ContainsKey(output)) if (AudioOutputFeedbacks.ContainsKey(output))
{ {
AudioOutputFeedbacks[output].FireUpdate(); AudioOutputFeedbacks[output].FireUpdate();
} }
} }
catch (NotSupportedException) catch (NotSupportedException)
{ {
if (outputCard != null) if (outputCard != null)
{ {
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name, Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name,
outputCard.AudioOutSourceFeedback, output); outputCard.AudioOutSourceFeedback, output);
} }
if (AudioOutputFeedbacks.ContainsKey(output)) if (AudioOutputFeedbacks.ContainsKey(output))
{ {
AudioOutputFeedbacks[output].FireUpdate(); AudioOutputFeedbacks[output].FireUpdate();
} }
} }
} }
else if (args.EventId == DMOutputEventIds.OutputNameEventId else if (args.EventId == DMOutputEventIds.OutputNameEventId
&& OutputNameFeedbacks.ContainsKey(output)) && OutputNameFeedbacks.ContainsKey(output))
@ -818,94 +849,94 @@ namespace PepperDash.Essentials.DM
Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType); Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType);
var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail
var output = Convert.ToUInt32(outputSelector); var output = Convert.ToUInt32(outputSelector);
var sigTypeIsUsbOrVideo = ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) || var sigTypeIsUsbOrVideo = ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) ||
((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) || ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) ||
((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput); ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput);
if ((input <= Dmps.NumberOfSwitcherInputs && output <= Dmps.NumberOfSwitcherOutputs && if ((input <= Dmps.NumberOfSwitcherInputs && output <= Dmps.NumberOfSwitcherOutputs &&
sigTypeIsUsbOrVideo) || sigTypeIsUsbOrVideo) ||
(input <= Dmps.NumberOfSwitcherInputs + 5 && output <= Dmps.NumberOfSwitcherOutputs && (input <= Dmps.NumberOfSwitcherInputs + 5 && output <= Dmps.NumberOfSwitcherOutputs &&
(sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)) (sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
{ {
// Check to see if there's an off timer waiting on this and if so, cancel // Check to see if there's an off timer waiting on this and if so, cancel
var key = new PortNumberType(output, sigType); var key = new PortNumberType(output, sigType);
if (input == 0) if (input == 0)
{ {
StartOffTimer(key); StartOffTimer(key);
} }
else if (key.Number > 0) else if (key.Number > 0)
{ {
if (RouteOffTimers.ContainsKey(key)) if (RouteOffTimers.ContainsKey(key))
{ {
Debug.Console(2, this, "{0} cancelling route off due to new source", output); Debug.Console(2, this, "{0} cancelling route off due to new source", output);
RouteOffTimers[key].Stop(); RouteOffTimers[key].Stop();
RouteOffTimers.Remove(key); RouteOffTimers.Remove(key);
} }
} }
DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput; DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput;
//if (inCard != null) //if (inCard != null)
//{ //{
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{ {
DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput;
//SystemControl.VideoEnter.BoolValue = true; //SystemControl.VideoEnter.BoolValue = true;
if (dmOutputCard != null) if (dmOutputCard != null)
dmOutputCard.VideoOut = dmInputCard; dmOutputCard.VideoOut = dmInputCard;
} }
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{ {
DMInput dmInputCard = null; DMInput dmInputCard = null;
if (input <= Dmps.NumberOfSwitcherInputs) if (input <= Dmps.NumberOfSwitcherInputs)
{ {
dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput;
} }
if (dmOutputCard != null) if (dmOutputCard != null)
try try
{ {
dmOutputCard.AudioOut = dmInputCard; dmOutputCard.AudioOut = dmInputCard;
} }
catch (NotSupportedException) catch (NotSupportedException)
{ {
Debug.Console(1, this, "Routing input {0} audio to output {1}", Debug.Console(1, this, "Routing input {0} audio to output {1}",
(eDmps34KAudioOutSource) input, (CrestronControlSystem.eDmps34K350COutputs) output); (eDmps34KAudioOutSource) input, (CrestronControlSystem.eDmps34K350COutputs) output);
dmOutputCard.AudioOutSource = (eDmps34KAudioOutSource) input; dmOutputCard.AudioOutSource = (eDmps34KAudioOutSource) input;
} }
} }
if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput) if ((sigType & eRoutingSignalType.UsbOutput) == eRoutingSignalType.UsbOutput)
{ {
DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput;
if (dmOutputCard != null) if (dmOutputCard != null)
dmOutputCard.USBRoutedTo = dmInputCard; dmOutputCard.USBRoutedTo = dmInputCard;
} }
if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput) if ((sigType & eRoutingSignalType.UsbInput) == eRoutingSignalType.UsbInput)
{ {
DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput; DMInput dmInputCard = input == 0 ? null : Dmps.SwitcherInputs[input] as DMInput;
if (dmInputCard != null) if (dmInputCard != null)
dmInputCard.USBRoutedTo = dmOutputCard; dmInputCard.USBRoutedTo = dmOutputCard;
} }
//} //}
//else //else
//{ //{
// Debug.Console(1, this, "Unable to execute route from input {0} to output {1}. Input card not available", inputSelector, outputSelector); // Debug.Console(1, this, "Unable to execute route from input {0} to output {1}. Input card not available", inputSelector, outputSelector);
//} //}
} }
else else
{ {
Debug.Console(1, this, "Unable to execute route from input {0} to output {1}", inputSelector, Debug.Console(1, this, "Unable to execute route from input {0} to output {1}", inputSelector,
outputSelector); outputSelector);
} }
} }
catch (Exception e) catch (Exception e)
{ {
@ -913,15 +944,15 @@ namespace PepperDash.Essentials.DM
} }
} }
#endregion #endregion
#region IRoutingNumeric Members #region IRoutingNumeric Members
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
{ {
ExecuteSwitch(inputSelector, outputSelector, sigType); ExecuteSwitch(inputSelector, outputSelector, sigType);
} }
#endregion #endregion
} }
} }

View file

@ -16,11 +16,14 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM.Chassis namespace PepperDash.Essentials.DM.Chassis
{ {
[Description("Wrapper class for all HdMdNxM4E switchers")] [Description("Wrapper class for all HdMdNxM4E switchers")]
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingInputsOutputs, IRoutingNumeric, IHasFeedback public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
{ {
private HdMdNxM _Chassis; private HdMdNxM _Chassis;
private HdMd4x14kE _Chassis4x1; private HdMd4x14kE _Chassis4x1;
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
public Dictionary<uint, string> InputNames { get; set; } public Dictionary<uint, string> InputNames { get; set; }
public Dictionary<uint, string> OutputNames { get; set; } public Dictionary<uint, string> OutputNames { get; set; }
@ -70,26 +73,34 @@ namespace PepperDash.Essentials.DM.Chassis
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{ {
var inputName = InputNames[i]; var index = i;
_Chassis.Inputs[i].Name.StringValue = inputName; var inputName = InputNames[index];
_Chassis.Inputs[index].Name.StringValue = inputName;
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo, InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, i, this)); eRoutingPortConnectionType.Hdmi, index, this)
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[i].VideoDetectedFeedback.BoolValue)); {
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[i].Name.StringValue)); FeedbackMatchObject = _Chassis.HdmiInputs[index]
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[i].HdmiInputPort.HdcpSupportOnFeedback.BoolValue)); });
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue));
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
} }
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{ {
var outputName = OutputNames[i]; var index = i;
var outputName = OutputNames[index];
_Chassis.Outputs[i].Name.StringValue = outputName; _Chassis.Outputs[i].Name.StringValue = outputName;
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo, OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, i, this)); eRoutingPortConnectionType.Hdmi, index, this)
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[i].VideoOutFeedback.Number)); {
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[i].Name.StringValue)); FeedbackMatchObject = _Chassis.HdmiOutputs[index]
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[i].VideoOutFeedback.NameFeedback.StringValue)); });
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue));
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
} }
_Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange); _Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange);
@ -102,6 +113,16 @@ namespace PepperDash.Essentials.DM.Chassis
#region Methods #region Methods
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
public void EnableHdcp(uint port) public void EnableHdcp(uint port)
{ {
if (port > _Chassis.NumberOfInputs) return; if (port > _Chassis.NumberOfInputs) return;
@ -328,44 +349,45 @@ namespace PepperDash.Essentials.DM.Chassis
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args) void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
{ {
if (args.DeviceOnLine) if (!args.DeviceOnLine) return;
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{ {
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++) _Chassis.Inputs[i].Name.StringValue = InputNames[i];
{ }
_Chassis.Inputs[i].Name.StringValue = InputNames[i]; for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
} {
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++) _Chassis.Outputs[i].Name.StringValue = OutputNames[i];
{ }
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
} foreach (var feedback in Feedbacks)
{
foreach (var feedback in Feedbacks) feedback.FireUpdate();
{
feedback.FireUpdate();
}
} }
} }
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args) void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
{ {
if (args.EventId == DMOutputEventIds.VideoOutEventId) if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++)
{ {
foreach (var item in VideoOutputRouteFeedbacks) var index = i;
{ var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback);
item.FireUpdate(); var localOutputPort =
} OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]);
VideoOutputRouteFeedbacks[i].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo));
} }
} }
void Chassis_DMInputChange(Switch device, DMInputEventArgs args) void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
{ {
if (args.EventId == DMInputEventIds.VideoDetectedEventId) if (args.EventId != DMInputEventIds.VideoDetectedEventId) return;
foreach (var item in VideoInputSyncFeedbacks)
{ {
foreach (var item in VideoInputSyncFeedbacks) item.FireUpdate();
{
item.FireUpdate();
}
} }
} }

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Sockets;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
@ -14,15 +15,19 @@ using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core.DeviceInfo;
namespace PepperDash.Essentials.DM.Endpoints.DGEs namespace PepperDash.Essentials.DM.Endpoints.DGEs
{ {
[Description("Wrapper class for DGE-100")] [Description("Wrapper class for DGE-100")]
public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec, IDeviceInfoProvider
{ {
private const int CtpPort = 41795;
private readonly Dge100 _dge; private readonly Dge100 _dge;
private readonly TsxCcsUcCodec100EthernetReservedSigs _dgeEthernetInfo;
public BasicTriListWithSmartObject Panel { get { return _dge; } } public BasicTriListWithSmartObject Panel { get { return _dge; } }
private DeviceConfig _dc; private DeviceConfig _dc;
@ -32,7 +37,14 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
public Dge100Controller(string key, string name, Dge100 device, DeviceConfig dc, CrestronTouchpanelPropertiesConfig props) public Dge100Controller(string key, string name, Dge100 device, DeviceConfig dc, CrestronTouchpanelPropertiesConfig props)
:base(key, name, device) :base(key, name, device)
{ {
_dge = device; _dge = device;
_dgeEthernetInfo = _dge.ExtenderEthernetReservedSigs;
_dgeEthernetInfo.DeviceExtenderSigChange += (extender, args) => UpdateDeviceInfo();
_dgeEthernetInfo.Use();
DeviceInfo = new DeviceInfo();
_dge.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
_dc = dc; _dc = dc;
@ -69,8 +81,86 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
#region ICec Members #region ICec Members
public Cec StreamCec { get { return _dge.HdmiOut.StreamCec; } } public Cec StreamCec { get { return _dge.HdmiOut.StreamCec; } }
#endregion #endregion
#region Implementation of IDeviceInfoProvider
public DeviceInfo DeviceInfo { get; private set; }
public event DeviceInfoChangeHandler DeviceInfoChanged;
public void UpdateDeviceInfo()
{
DeviceInfo.IpAddress = _dgeEthernetInfo.IpAddressFeedback.StringValue;
DeviceInfo.MacAddress = _dgeEthernetInfo.MacAddressFeedback.StringValue;
GetFirmwareAndSerialInfo();
OnDeviceInfoChange();
}
private void GetFirmwareAndSerialInfo()
{
if (String.IsNullOrEmpty(_dgeEthernetInfo.IpAddressFeedback.StringValue))
{
Debug.Console(1, this, "IP Address information not yet received. No device is online");
return;
}
var tcpClient = new GenericTcpIpClient("", _dgeEthernetInfo.IpAddressFeedback.StringValue, CtpPort, 1024){AutoReconnect = false};
var gather = new CommunicationGather(tcpClient, "\r\n\r\n");
tcpClient.ConnectionChange += (sender, args) =>
{
if (!args.Client.IsConnected)
{
return;
}
args.Client.SendText("ver\r\n");
};
gather.LineReceived += (sender, args) =>
{
if (args.Text.ToLower().Contains("host"))
{
DeviceInfo.HostName = args.Text.Split(';')[1].Trim();
tcpClient.Disconnect();
return;
}
//ignore console prompt
if (args.Text.ToLower().Contains(">"))
{
return;
}
if (!args.Text.ToLower().Contains("dge"))
{
return;
}
DeviceInfo.SerialNumber = args.Text.Split('[')[1].Split(' ')[4].Replace("#", "");
DeviceInfo.FirmwareVersion = args.Text.Split('[')[1].Split(' ')[1];
tcpClient.SendText("host\r\n");
};
tcpClient.Connect();
}
private void OnDeviceInfoChange()
{
var handler = DeviceInfoChanged;
if (handler == null) return;
handler(this, new DeviceInfoEventArgs(DeviceInfo));
}
#endregion
} }
public class Dge100ControllerFactory : EssentialsDeviceFactory<Dge100Controller> public class Dge100ControllerFactory : EssentialsDeviceFactory<Dge100Controller>

View file

@ -13,7 +13,7 @@ using PepperDash.Core;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
[Description("Wrapper Class for DM-RMC-4K-Z-SCALER-C")] [Description("Wrapper Class for DM-RMC-4K-Z-SCALER-C")]
public class DmRmc4kZScalerCController : DmRmcControllerBase, IRmcRouting, public class DmRmc4kZScalerCController : DmRmcControllerBase, IRmcRoutingWithFeedback,
IIROutputPorts, IComPorts, ICec IIROutputPorts, IComPorts, ICec
{ {
private readonly DmRmc4kzScalerC _rmc; private readonly DmRmc4kzScalerC _rmc;
@ -31,14 +31,34 @@ namespace PepperDash.Essentials.DM
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; } public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
public DmRmc4kZScalerCController(string key, string name, DmRmc4kzScalerC rmc) public DmRmc4kZScalerCController(string key, string name, DmRmc4kzScalerC rmc)
: base(key, name, rmc) : base(key, name, rmc)
{ {
_rmc = rmc; _rmc = rmc;
DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo, DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.DmCat, 0, this); eRoutingPortConnectionType.DmCat, 0, this)
{
FeedbackMatchObject = 1
};
HdmiIn = new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.AudioVideo, HdmiIn = new RoutingInputPort(DmPortName.HdmiIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, 0, this); eRoutingPortConnectionType.Hdmi, 0, this)
{
FeedbackMatchObject = 2
};
HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo, HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, null, this); eRoutingPortConnectionType.Hdmi, null, this);
@ -55,12 +75,20 @@ namespace PepperDash.Essentials.DM
_rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange; _rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
_rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange; _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
_rmc.OnlineStatusChange += _rmc_OnlineStatusChange;
// Set Ports for CEC // Set Ports for CEC
HdmiOut.Port = _rmc.HdmiOutput; HdmiOut.Port = _rmc.HdmiOutput;
AudioVideoSourceNumericFeedback = new IntFeedback(() => (ushort)(_rmc.SelectedSourceFeedback)); AudioVideoSourceNumericFeedback = new IntFeedback(() => (ushort)(_rmc.SelectedSourceFeedback));
} }
private void _rmc_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
AudioVideoSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioVideoSourceNumericFeedback.UShortValue, eRoutingSignalType.AudioVideo));
}
void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args) void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args)
{ {
if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId || if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId ||
@ -71,7 +99,12 @@ namespace PepperDash.Essentials.DM
if (args.EventId == EndpointOutputStreamEventIds.SelectedSourceFeedbackEventId) if (args.EventId == EndpointOutputStreamEventIds.SelectedSourceFeedbackEventId)
{ {
var localInputPort =
InputPorts.FirstOrDefault(p => (int)p.FeedbackMatchObject == AudioVideoSourceNumericFeedback.UShortValue);
AudioVideoSourceNumericFeedback.FireUpdate(); AudioVideoSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioVideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputPort, eRoutingSignalType.AudioVideo));
} }
} }

View file

@ -8,14 +8,16 @@ using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.DeviceInfo;
using PepperDash.Essentials.DM.Config; using PepperDash.Essentials.DM.Config;
using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
[Description("Wrapper class for all DM-RMC variants")] [Description("Wrapper class for all DM-RMC variants")]
public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice, IDeviceInfoProvider
{ {
private const int CtpPort = 41795;
private readonly EndpointReceiverBase _rmc; //kept here just in case. Only property or method on this class that's not device-specific is the DMOutput that it's attached to. private readonly EndpointReceiverBase _rmc; //kept here just in case. Only property or method on this class that's not device-specific is the DMOutput that it's attached to.
public StringFeedback VideoOutputResolutionFeedback { get; protected set; } public StringFeedback VideoOutputResolutionFeedback { get; protected set; }
@ -32,6 +34,10 @@ namespace PepperDash.Essentials.DM
PreventRegistration = _rmc.DMOutput != null; PreventRegistration = _rmc.DMOutput != null;
AddToFeedbackList(VideoOutputResolutionFeedback, EdidManufacturerFeedback, EdidSerialNumberFeedback, EdidNameFeedback, EdidPreferredTimingFeedback); AddToFeedbackList(VideoOutputResolutionFeedback, EdidManufacturerFeedback, EdidSerialNumberFeedback, EdidNameFeedback, EdidPreferredTimingFeedback);
DeviceInfo = new DeviceInfo();
_rmc.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); };
} }
protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
@ -79,7 +85,106 @@ namespace PepperDash.Essentials.DM
trilist.SetUShortSigAction(joinMap.AudioVideoSource.JoinNumber, a => routing.ExecuteNumericSwitch(a, 1, eRoutingSignalType.AudioVideo)); trilist.SetUShortSigAction(joinMap.AudioVideoSource.JoinNumber, a => routing.ExecuteNumericSwitch(a, 1, eRoutingSignalType.AudioVideo));
} }
}
#region Implementation of IDeviceInfoProvider
public DeviceInfo DeviceInfo { get; private set; }
public event DeviceInfoChangeHandler DeviceInfoChanged;
public void UpdateDeviceInfo()
{
Debug.Console(1, this, "Updating Device Info");
if (_rmc.ConnectedIpList.Count == 0)
{
Debug.Console(1, this, "IP Address information not yet received. No device is online");
return;
}
DeviceInfo.IpAddress = _rmc.ConnectedIpList[0].DeviceIpAddress;
foreach (var ip in _rmc.ConnectedIpList)
{
Debug.Console(0, this, "Connected IP Address: {0}", ip.DeviceIpAddress);
}
GetFirmwareAndSerialInfo();
OnDeviceInfoChange();
}
private void GetFirmwareAndSerialInfo()
{
var tcpClient = new GenericTcpIpClient(String.Format("{0}-devInfoSocket", Key), _rmc.ConnectedIpList[0].DeviceIpAddress, CtpPort, 1024)
{
AutoReconnect = false,
};
var gather = new CommunicationGather(tcpClient, "\r\n\r\n");
tcpClient.ConnectionChange += (sender, args) =>
{
if (!args.Client.IsConnected)
{
OnDeviceInfoChange();
return;
}
args.Client.SendText("ver\r\n");
};
gather.LineReceived += (sender, args) =>
{
//ignore console prompt
if (args.Text.ToLower().Contains(">"))
{
return;
}
if (args.Text.ToLower().Contains("host"))
{
DeviceInfo.HostName = args.Text.Split(':')[1].Trim();
tcpClient.SendText("maca\r\n");
return;
}
if (args.Text.ToLower().Contains("mac"))
{
DeviceInfo.MacAddress = args.Text.Split(':')[1].Trim().Replace(" ", ":");
tcpClient.Disconnect();
return;
}
if (!args.Text.ToLower().Contains("rmc"))
{
return;
}
DeviceInfo.SerialNumber = args.Text.Split('[')[1].Split(' ')[4].Replace("#", "");
DeviceInfo.FirmwareVersion = args.Text.Split('[')[1].Split(' ')[1];
tcpClient.SendText("host\r\n");
};
tcpClient.Connect();
}
private void OnDeviceInfoChange()
{
var handler = DeviceInfoChanged;
if (handler == null) return;
handler(this, new DeviceInfoEventArgs(DeviceInfo));
}
#endregion
}
public abstract class DmHdBaseTControllerBase : CrestronGenericBaseDevice public abstract class DmHdBaseTControllerBase : CrestronGenericBaseDevice
{ {

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Linq;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM;
@ -17,7 +18,7 @@ namespace PepperDash.Essentials.DM
/// Controller class for all DM-TX-201C/S/F transmitters /// Controller class for all DM-TX-201C/S/F transmitters
/// </summary> /// </summary>
[Description("Wrapper class for DM-TX-200-C")] [Description("Wrapper class for DM-TX-200-C")]
public class DmTx200Controller : DmTxControllerBase, ITxRouting, IHasFreeRun, IVgaBrightnessContrastControls public class DmTx200Controller : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
{ {
public DmTx200C2G Tx { get; private set; } public DmTx200C2G Tx { get; private set; }
@ -35,7 +36,21 @@ namespace PepperDash.Essentials.DM
public BoolFeedback FreeRunEnabledFeedback { get; protected set; } public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; } public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; } public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
@ -85,14 +100,22 @@ namespace PepperDash.Essentials.DM
public DmTx200Controller(string key, string name, DmTx200C2G tx) public DmTx200Controller(string key, string name, DmTx200C2G tx)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, DmTx200Base.eSourceSelection.Digital, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput)); DmTx200Base.eSourceSelection.Digital, this,
VgaInput = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput))
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, DmTx200Base.eSourceSelection.Analog, this, {
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)); FeedbackMatchObject = DmTx200Base.eSourceSelection.Digital
};
VgaInput = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, DmTx200Base.eSourceSelection.Analog, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = DmTx200Base.eSourceSelection.Analog
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString()); () => ActualActiveVideoInput.ToString());
@ -195,12 +218,19 @@ namespace PepperDash.Essentials.DM
} }
} }
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{ {
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection) p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection) p.Selector == Tx.AudioSourceFeedback);
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
} }
public override bool CustomActivate() public override bool CustomActivate()
@ -303,14 +333,18 @@ namespace PepperDash.Essentials.DM
switch (id) switch (id)
{ {
case EndpointTransmitterBase.VideoSourceFeedbackEventId: case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break; break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId: case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback); Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break; break;
} }
} }

View file

@ -4,6 +4,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using System.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
@ -14,8 +15,8 @@ namespace PepperDash.Essentials.DM
/// <summary> /// <summary>
/// Controller class for all DM-TX-201C/S/F transmitters /// Controller class for all DM-TX-201C/S/F transmitters
/// </summary> /// </summary>
[Description("Wrapper class for DM-TX-201-C")] [Description("Wrapper class for DM-TX-201-C")]
public class DmTx201CController : DmTxControllerBase, ITxRouting, IHasFreeRun, IVgaBrightnessContrastControls public class DmTx201CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
{ {
public DmTx201C Tx { get; private set; } public DmTx201C Tx { get; private set; }
@ -34,7 +35,20 @@ namespace PepperDash.Essentials.DM
public BoolFeedback FreeRunEnabledFeedback { get; protected set; } public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; } public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; } public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
@ -89,14 +103,22 @@ namespace PepperDash.Essentials.DM
public DmTx201CController(string key, string name, DmTx201C tx) public DmTx201CController(string key, string name, DmTx201C tx)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, DmTx200Base.eSourceSelection.Digital, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput)); DmTx200Base.eSourceSelection.Digital, this,
VgaInput = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput))
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, DmTx200Base.eSourceSelection.Analog, this, {
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)); FeedbackMatchObject = DmTx200Base.eSourceSelection.Digital
};
VgaInput = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, DmTx200Base.eSourceSelection.Analog, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = DmTx200Base.eSourceSelection.Analog
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString()); () => ActualActiveVideoInput.ToString());
@ -190,16 +212,23 @@ namespace PepperDash.Essentials.DM
VgaContrastFeedback.FireUpdate(); VgaContrastFeedback.FireUpdate();
break; break;
} }
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate();
} }
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.AudioSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
}
private void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) private void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{ {
switch (args.EventId) switch (args.EventId)
@ -312,23 +341,26 @@ namespace PepperDash.Essentials.DM
} }
void Tx_BaseEvent(GenericBase device, BaseEventArgs args) void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
{ {
var id = args.EventId; var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId); Debug.Console(2, this, "EventId {0}", args.EventId);
switch (id) switch (id)
{ {
case EndpointTransmitterBase.VideoSourceFeedbackEventId: case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break; break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId: case EndpointTransmitterBase.AudioSourceFeedbackEventId:
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback); var localInputAudioPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break; break;
} }
} }
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)

View file

@ -4,6 +4,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints; using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using System.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
@ -15,7 +16,7 @@ namespace PepperDash.Essentials.DM
/// Controller class for all DM-TX-201S/F transmitters /// Controller class for all DM-TX-201S/F transmitters
/// </summary> /// </summary>
[Description("Wrapper class for DM-TX-201-S/F")] [Description("Wrapper class for DM-TX-201-S/F")]
public class DmTx201SController : DmTxControllerBase, ITxRouting, IHasFreeRun, IVgaBrightnessContrastControls public class DmTx201SController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
{ {
public DmTx201S Tx { get; private set; } public DmTx201S Tx { get; private set; }
@ -36,6 +37,21 @@ namespace PepperDash.Essentials.DM
public IntFeedback VgaBrightnessFeedback { get; protected set; } public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; } public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
/// </summary> /// </summary>
@ -92,11 +108,19 @@ namespace PepperDash.Essentials.DM
Tx = tx; Tx = tx;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, DmTx200Base.eSourceSelection.Digital, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput)); DmTx200Base.eSourceSelection.Digital, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput))
{
FeedbackMatchObject = DmTx200Base.eSourceSelection.Digital
};
VgaInput = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, VgaInput = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, DmTx200Base.eSourceSelection.Analog, this, eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, DmTx200Base.eSourceSelection.Analog, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)); VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = DmTx200Base.eSourceSelection.Analog
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString()); () => ActualActiveVideoInput.ToString());
@ -194,11 +218,18 @@ namespace PepperDash.Essentials.DM
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{ {
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.AudioSourceFeedback);
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
} OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
}
private void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) private void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{ {
@ -319,17 +350,20 @@ namespace PepperDash.Essentials.DM
switch (id) switch (id)
{ {
case EndpointTransmitterBase.VideoSourceFeedbackEventId: case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break; break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId: case EndpointTransmitterBase.AudioSourceFeedbackEventId:
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback); var localInputAudioPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break; break;
} }
} }
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args) void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{ {

View file

@ -20,7 +20,7 @@ namespace PepperDash.Essentials.DM
using eVst = DmTx401C.eSourceSelection; using eVst = DmTx401C.eSourceSelection;
[Description("Wrapper class for DM-TX-401-C")] [Description("Wrapper class for DM-TX-401-C")]
public class DmTx401CController : DmTxControllerBase, ITxRouting, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls public class DmTx401CController : DmTxControllerBase, ITxRoutingWithFeedback, IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
{ {
public DmTx401C Tx { get; private set; } public DmTx401C Tx { get; private set; }
@ -41,7 +41,21 @@ namespace PepperDash.Essentials.DM
public BoolFeedback FreeRunEnabledFeedback { get; protected set; } public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; } public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; } public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
@ -104,20 +118,33 @@ namespace PepperDash.Essentials.DM
HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput)); VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInput))
{
FeedbackMatchObject = eVst.HDMI
};
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn, DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.DisplayPort, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.DisplayPort, this,
VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput)); VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput))
{
FeedbackMatchObject = eVst.DisplayPort
};
VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.VGA, this, eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.VGA, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)); VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = eVst.VGA
};
CompositeIn = new RoutingInputPortWithVideoStatuses(DmPortName.CompositeIn, CompositeIn = new RoutingInputPortWithVideoStatuses(DmPortName.CompositeIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Composite, eVst.Composite, this, eRoutingSignalType.Video, eRoutingPortConnectionType.Composite, eVst.Composite, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)); VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = eVst.Composite
};
Tx.HdmiInput.InputStreamChange += HdmiInputStreamChangeEvent; Tx.HdmiInput.InputStreamChange += HdmiInputStreamChangeEvent;
Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChangeEvent; Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChangeEvent;
Tx.BaseEvent += Tx_BaseEvent; Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange; Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange; tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
@ -286,6 +313,20 @@ namespace PepperDash.Essentials.DM
Tx.AudioSource = (eVst)inputSelector; Tx.AudioSource = (eVst)inputSelector;
} }
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
}
void Tx_BaseEvent(GenericBase device, BaseEventArgs args) void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
{ {
var id = args.EventId; var id = args.EventId;
@ -294,16 +335,20 @@ namespace PepperDash.Essentials.DM
switch (id) switch (id)
{ {
case EndpointTransmitterBase.VideoSourceFeedbackEventId: case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break; break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId: case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback); Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break; break;
} }
} }
void VideoControls_ControlChange(object sender, GenericEventArgs args) void VideoControls_ControlChange(object sender, GenericEventArgs args)
{ {

View file

@ -20,8 +20,8 @@ namespace PepperDash.Essentials.DM
using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType; using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType; using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
[Description("Wrapper class for DM-TX-4K-202-C")] [Description("Wrapper class for DM-TX-4K-202-C")]
public class DmTx4k202CController : DmTxControllerBase, ITxRouting, IHasFeedback, public class DmTx4k202CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
IIROutputPorts, IComPorts IIROutputPorts, IComPorts
{ {
public DmTx4k202C Tx { get; private set; } public DmTx4k202C Tx { get; private set; }
@ -37,7 +37,21 @@ namespace PepperDash.Essentials.DM
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; } public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; } public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; } public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; } //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; } //public override ushort HdcpSupportCapability { get; protected set; }
@ -80,106 +94,121 @@ namespace PepperDash.Essentials.DM
{ {
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut }; return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
} }
} }
public DmTx4k202CController(string key, string name, DmTx4k202C tx)
: base(key, name, tx) public DmTx4k202CController(string key, string name, DmTx4k202C tx)
{ : base(key, name, tx)
Tx = tx; {
Tx = tx;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1])); eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, {
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2])); FeedbackMatchObject = eVst.Hdmi1
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", };
() => ActualActiveVideoInput.ToString()); HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
{
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; FeedbackMatchObject = eVst.Hdmi2
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; };
Tx.BaseEvent += Tx_BaseEvent; ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString());
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback); Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback); Tx.BaseEvent += Tx_BaseEvent;
HdcpStateFeedback = Tx.OnlineStatusChange += Tx_OnlineStatusChange;
new IntFeedback(
() => VideoSourceNumericFeedback = new IntFeedback(() => (int) Tx.VideoSourceFeedback);
tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
? (int) tx.HdmiInputs[1].HdcpCapabilityFeedback AudioSourceNumericFeedback = new IntFeedback(() => (int) Tx.AudioSourceFeedback);
: (int) tx.HdmiInputs[2].HdcpCapabilityFeedback);
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability",
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support; () => (int) tx.HdmiInputs[1].HdcpCapabilityFeedback);
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue); HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability",
() => (int) tx.HdmiInputs[2].HdcpCapabilityFeedback);
Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
HdcpStateFeedback =
var combinedFuncs = new VideoStatusFuncsWrapper new IntFeedback(
{ () =>
HdcpActiveFeedbackFunc = () => tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
(ActualActiveVideoInput == eVst.Hdmi1 ? (int) tx.HdmiInputs[1].HdcpCapabilityFeedback
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue) : (int) tx.HdmiInputs[2].HdcpCapabilityFeedback);
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue), HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
HdcpStateFeedbackFunc = () => Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool) tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
{
if (ActualActiveVideoInput == eVst.Hdmi1) Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool) tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
if (ActualActiveVideoInput == eVst.Hdmi2) var combinedFuncs = new VideoStatusFuncsWrapper
return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString(); {
return ""; HdcpActiveFeedbackFunc = () =>
}, (ActualActiveVideoInput == eVst.Hdmi1
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
VideoResolutionFeedbackFunc = () => || (ActualActiveVideoInput == eVst.Hdmi2
{ && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
if (ActualActiveVideoInput == eVst.Hdmi1)
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString(); HdcpStateFeedbackFunc = () =>
if (ActualActiveVideoInput == eVst.Hdmi2) {
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString(); if (ActualActiveVideoInput == eVst.Hdmi1)
return ""; return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
}, if (ActualActiveVideoInput == eVst.Hdmi2)
VideoSyncFeedbackFunc = () => return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
(ActualActiveVideoInput == eVst.Hdmi1 return "";
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue) },
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue) VideoResolutionFeedbackFunc = () =>
{
}; if (ActualActiveVideoInput == eVst.Hdmi1)
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn, if (ActualActiveVideoInput == eVst.Hdmi2)
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs); return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
return "";
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, },
eRoutingPortConnectionType.DmCat, null, this); VideoSyncFeedbackFunc = () =>
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, (ActualActiveVideoInput == eVst.Hdmi1
eRoutingPortConnectionType.Hdmi, null, this); && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback, };
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback, AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback); eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this,
combinedFuncs);
// Set Ports for CEC
HdmiIn1.Port = Tx.HdmiInputs[1]; DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
HdmiIn2.Port = Tx.HdmiInputs[2]; eRoutingPortConnectionType.DmCat, null, this);
HdmiLoopOut.Port = Tx.HdmiOutput; HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut,
DmOut.Port = Tx.DmOutput; 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() public override bool CustomActivate()
{ {
// Link up all of these damned events to the various RoutingPorts via a helper handler // Link up all of these damned events to the various RoutingPorts via a helper handler
@ -294,26 +323,43 @@ namespace PepperDash.Essentials.DM
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
break; break;
} }
} }
void Tx_BaseEvent(GenericBase device, BaseEventArgs args) void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{ {
var id = args.EventId; var localVideoInputPort =
Debug.Console(2, this, "EventId {0}", args.EventId); InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
switch (id) InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
{
case EndpointTransmitterBase.VideoSourceFeedbackEventId: ActiveVideoInputFeedback.FireUpdate();
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
ActiveVideoInputFeedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
break; }
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback); void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
AudioSourceNumericFeedback.FireUpdate(); {
break; var id = args.EventId;
} Debug.Console(2, this, "EventId {0}", args.EventId);
switch (id)
{
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
} }
/// <summary> /// <summary>

View file

@ -21,7 +21,7 @@ namespace PepperDash.Essentials.DM
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType; using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
[Description("Wrapper class for DM-TX-4K-302-C")] [Description("Wrapper class for DM-TX-4K-302-C")]
public class DmTx4k302CController : DmTxControllerBase, ITxRouting, IHasFeedback, public class DmTx4k302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
{ {
public DmTx4k302C Tx { get; private set; } public DmTx4k302C Tx { get; private set; }
@ -44,7 +44,21 @@ namespace PepperDash.Essentials.DM
public BoolFeedback FreeRunEnabledFeedback { get; protected set; } public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
public IntFeedback VgaBrightnessFeedback { get; protected set; } public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; } public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
@ -95,13 +109,24 @@ namespace PepperDash.Essentials.DM
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1])); VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
{
FeedbackMatchObject = eVst.Hdmi1
};
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2])); VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
{
FeedbackMatchObject = eVst.Hdmi2
};
VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.Vga, this, eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.Vga, this,
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput)); VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = eVst.Vga
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString()); () => ActualActiveVideoInput.ToString());
@ -110,6 +135,8 @@ namespace PepperDash.Essentials.DM
Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange; Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
Tx.BaseEvent += Tx_BaseEvent; Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback); AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
@ -387,23 +414,42 @@ namespace PepperDash.Essentials.DM
break; break;
} }
} }
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
}
void Tx_BaseEvent(GenericBase device, BaseEventArgs args) void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
{ {
var id = args.EventId; var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
switch (id) switch (id)
{ {
case EndpointTransmitterBase.VideoSourceFeedbackEventId: case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break; break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId: case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback); Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break; break;
} }
} }
/// <summary> /// <summary>
/// Relays the input stream change to the appropriate RoutingInputPort. /// Relays the input stream change to the appropriate RoutingInputPort.

View file

@ -1,4 +1,6 @@
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using System;
using System.Linq;
//using Crestron.SimplSharpPro.DeviceSupport; //using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM;
@ -12,9 +14,9 @@ using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
using eVst = eX02VideoSourceType; using eVst = eX02VideoSourceType;
using eAst = eX02AudioSourceType; using eAst = eX02AudioSourceType;
public class DmTx4kz202CController : DmTxControllerBase, ITxRouting, public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback,
IIROutputPorts, IComPorts IIROutputPorts, IComPorts
{ {
public DmTx4kz202C Tx { get; private set; } public DmTx4kz202C Tx { get; private set; }
@ -33,7 +35,21 @@ namespace PepperDash.Essentials.DM
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; } public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; } //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; } //public override ushort HdcpSupportCapability { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
@ -73,14 +89,21 @@ namespace PepperDash.Essentials.DM
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx) public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1])); VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, {
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, FeedbackMatchObject = eVst.Hdmi1
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2])); };
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
{
FeedbackMatchObject = eVst.Hdmi2
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString()); () => ActualActiveVideoInput.ToString());
@ -89,6 +112,7 @@ namespace PepperDash.Essentials.DM
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent; Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
Tx.BaseEvent += Tx_BaseEvent; Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
@ -282,27 +306,44 @@ namespace PepperDash.Essentials.DM
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
break; break;
} }
} }
void Tx_BaseEvent(GenericBase device, BaseEventArgs args) void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{ {
var id = args.EventId; var localVideoInputPort =
Debug.Console(2, this, "EventId {0}", args.EventId); InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
switch (id) InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
{
case EndpointTransmitterBase.VideoSourceFeedbackEventId: ActiveVideoInputFeedback.FireUpdate();
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback); VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); AudioSourceNumericFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
AudioSourceNumericFeedback.FireUpdate(); OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
ActiveVideoInputFeedback.FireUpdate(); }
break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
Debug.Console(2, this, " Audio Source : {0}", Tx.AudioSourceFeedback); void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
AudioSourceNumericFeedback.FireUpdate(); {
break; var id = args.EventId;
} Debug.Console(2, this, "EventId {0}", args.EventId);
switch (id)
{
case EndpointTransmitterBase.VideoSourceFeedbackEventId:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
} }
/// <summary> /// <summary>

View file

@ -1,4 +1,6 @@
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using System;
using System.Linq;
//using Crestron.SimplSharpPro.DeviceSupport; //using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM;
@ -15,8 +17,8 @@ namespace PepperDash.Essentials.DM
using eAst = eX02AudioSourceType; using eAst = eX02AudioSourceType;
[Description("Wrapper class for DM-TX-4K-Z-302-C")] [Description("Wrapper class for DM-TX-4K-Z-302-C")]
public class DmTx4kz302CController : DmTxControllerBase, ITxRouting, IHasFeedback, public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
IIROutputPorts, IComPorts IIROutputPorts, IComPorts
{ {
public DmTx4kz302C Tx { get; private set; } public DmTx4kz302C Tx { get; private set; }
@ -37,7 +39,20 @@ namespace PepperDash.Essentials.DM
public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; } public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; } //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; } //public override ushort HdcpSupportCapability { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
@ -83,13 +98,22 @@ namespace PepperDash.Essentials.DM
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1])); VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
{
FeedbackMatchObject = eVst.Hdmi1
};
HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2, HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2])); VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn, {
FeedbackMatchObject = eVst.Hdmi2
};
DisplayPortIn = new RoutingInputPortWithVideoStatuses(DmPortName.DisplayPortIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DisplayPort, eVst.DisplayPort, this,
VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput)); VideoStatusHelper.GetDisplayPortInputStatusFuncs(tx.DisplayPortInput))
{
FeedbackMatchObject = eVst.DisplayPort
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput", ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString()); () => ActualActiveVideoInput.ToString());
@ -97,6 +121,7 @@ namespace PepperDash.Essentials.DM
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent; Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange; Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange;
Tx.BaseEvent += Tx_BaseEvent; Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback); AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
@ -293,23 +318,44 @@ namespace PepperDash.Essentials.DM
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate(); if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
break; break;
} }
} }
void Tx_BaseEvent(GenericBase device, BaseEventArgs args) void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
{ {
var id = args.EventId; var localVideoInputPort =
switch (id) InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
{ var localAudioInputPort =
case EndpointTransmitterBase.VideoSourceFeedbackEventId: InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate(); ActiveVideoInputFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate(); VideoSourceNumericFeedback.FireUpdate();
break; AudioSourceNumericFeedback.FireUpdate();
case EndpointTransmitterBase.AudioSourceFeedbackEventId: OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback); OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
AudioSourceNumericFeedback.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:
var localVideoInputPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
VideoSourceNumericFeedback.FireUpdate();
ActiveVideoInputFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
} }
/// <summary> /// <summary>

View file

@ -59,7 +59,7 @@
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath> <HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
</Reference> </Reference>

View file

@ -181,14 +181,18 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
}); });
} }
if (cameraDevice is IPower) var powerCamera = cameraDevice as IHasPowerControl;
if (powerCamera != null)
{ {
var powerCamera = cameraDevice as IPower;
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () => powerCamera.PowerOn()); trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () => powerCamera.PowerOn());
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () => powerCamera.PowerOff()); trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () => powerCamera.PowerOff());
powerCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]); var powerFbCamera = powerCamera as IHasPowerControlWithFeedback;
powerCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]); if (powerFbCamera != null)
{
powerFbCamera.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
powerFbCamera.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
}
} }
if (cameraDevice is ICommunicationMonitor) if (cameraDevice is ICommunicationMonitor)

View file

@ -92,8 +92,6 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary> /// </summary>
public interface IHasCameraPanControl : IHasCameraControls public interface IHasCameraPanControl : IHasCameraControls
{ {
// void PanLeft(bool pressRelease);
// void PanRight(bool pressRelease);
void PanLeft(); void PanLeft();
void PanRight(); void PanRight();
void PanStop(); void PanStop();
@ -104,8 +102,6 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary> /// </summary>
public interface IHasCameraTiltControl : IHasCameraControls public interface IHasCameraTiltControl : IHasCameraControls
{ {
// void TiltDown(bool pressRelease);
// void TildUp(bool pressRelease);
void TiltDown(); void TiltDown();
void TiltUp(); void TiltUp();
void TiltStop(); void TiltStop();
@ -116,8 +112,6 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
/// </summary> /// </summary>
public interface IHasCameraZoomControl : IHasCameraControls public interface IHasCameraZoomControl : IHasCameraControls
{ {
// void ZoomIn(bool pressRelease);
// void ZoomOut(bool pressRelease);
void ZoomIn(); void ZoomIn();
void ZoomOut(); void ZoomOut();
void ZoomStop(); void ZoomStop();
@ -135,6 +129,13 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
void TriggerAutoFocus(); void TriggerAutoFocus();
} }
public interface IHasAutoFocusMode
{
void SetFocusModeAuto();
void SetFocusModeManual();
void ToggleFocusMode();
}
public interface IHasCameraAutoMode : IHasCameraControls public interface IHasCameraAutoMode : IHasCameraControls
{ {
void CameraAutoModeOn(); void CameraAutoModeOn();

View file

@ -12,29 +12,86 @@ using PepperDash.Essentials.Devices.Common.Codec;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp.Reflection; using Crestron.SimplSharp.Reflection;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.Cameras namespace PepperDash.Essentials.Devices.Common.Cameras
{ {
public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IPower, IBridgeAdvanced public class CameraVisca : CameraBase, IHasCameraPtzControl, ICommunicationMonitor, IHasCameraPresets, IHasPowerControlWithFeedback, IBridgeAdvanced, IHasCameraFocusControl, IHasAutoFocusMode
{ {
CameraViscaPropertiesConfig PropertiesConfig;
public IBasicCommunication Communication { get; private set; } public IBasicCommunication Communication { get; private set; }
public CommunicationGather PortGather { get; private set; }
public StatusMonitorBase CommunicationMonitor { get; private set; } public StatusMonitorBase CommunicationMonitor { get; private set; }
public byte PanSpeed = 0x10; /// <summary>
public byte TiltSpeed = 0x10; /// Used to store the actions to parse inquiry responses as the inquiries are sent
/// </summary>
private CrestronQueue<Action<byte[]>> InquiryResponseQueue;
/// <summary>
/// Camera ID (Default 1)
/// </summary>
public byte ID = 0x01;
public byte ResponseID;
public byte PanSpeedSlow = 0x10;
public byte TiltSpeedSlow = 0x10;
public byte PanSpeedFast = 0x13;
public byte TiltSpeedFast = 0x13;
private bool IsMoving; private bool IsMoving;
private bool IsZooming; private bool IsZooming;
public bool PowerIsOn { get; private set; }
bool _powerIsOn;
public bool PowerIsOn
{
get
{
return _powerIsOn;
}
private set
{
if (value != _powerIsOn)
{
_powerIsOn = value;
PowerIsOnFeedback.FireUpdate();
CameraIsOffFeedback.FireUpdate();
}
}
}
const byte ZoomInCmd = 0x02;
const byte ZoomOutCmd = 0x03;
const byte ZoomStopCmd = 0x00;
/// <summary>
/// Used to determine when to move the camera at a faster speed if a direction is held
/// </summary>
CTimer SpeedTimer;
// TODO: Implment speed timer for PTZ controls
long FastSpeedHoldTimeMs = 2000;
byte[] IncomingBuffer = new byte[] { }; byte[] IncomingBuffer = new byte[] { };
public BoolFeedback PowerIsOnFeedback { get; private set; } public BoolFeedback PowerIsOnFeedback { get; private set; }
public CameraVisca(string key, string name, IBasicCommunication comm, CameraPropertiesConfig props) : public CameraVisca(string key, string name, IBasicCommunication comm, CameraViscaPropertiesConfig props) :
base(key, name) base(key, name)
{ {
InquiryResponseQueue = new CrestronQueue<Action<byte[]>>(15);
Presets = props.Presets; Presets = props.Presets;
PropertiesConfig = props;
ID = (byte)(props.Id + 0x80);
ResponseID = (byte)((props.Id * 0x10) + 0x80);
SetupCameraSpeeds();
OutputPorts.Add(new RoutingOutputPort("videoOut", eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, this, true)); OutputPorts.Add(new RoutingOutputPort("videoOut", eRoutingSignalType.Video, eRoutingPortConnectionType.None, null, this, true));
// Default to all capabilties // Default to all capabilties
@ -51,11 +108,10 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
{ {
// This instance uses RS-232 control // This instance uses RS-232 control
} }
PortGather = new CommunicationGather(Communication, "\xFF");
Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived); Communication.BytesReceived += new EventHandler<GenericCommMethodReceiveBytesArgs>(Communication_BytesReceived);
PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; }); PowerIsOnFeedback = new BoolFeedback(() => { return PowerIsOn; });
CameraIsOffFeedback = new BoolFeedback(() => { return !PowerIsOn; });
if (props.CommunicationMonitorProperties != null) if (props.CommunicationMonitorProperties != null)
{ {
@ -66,9 +122,38 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF"); CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 20000, 120000, 300000, "\x81\x09\x04\x00\xFF");
} }
DeviceManager.AddDevice(CommunicationMonitor); DeviceManager.AddDevice(CommunicationMonitor);
} }
/// <summary>
/// Sets up camera speed values based on config
/// </summary>
void SetupCameraSpeeds()
{
if (PropertiesConfig.FastSpeedHoldTimeMs > 0)
{
FastSpeedHoldTimeMs = PropertiesConfig.FastSpeedHoldTimeMs;
}
if (PropertiesConfig.PanSpeedSlow > 0)
{
PanSpeedSlow = (byte)PropertiesConfig.PanSpeedSlow;
}
if (PropertiesConfig.PanSpeedFast > 0)
{
PanSpeedFast = (byte)PropertiesConfig.PanSpeedFast;
}
if (PropertiesConfig.TiltSpeedSlow > 0)
{
TiltSpeedSlow = (byte)PropertiesConfig.TiltSpeedSlow;
}
if (PropertiesConfig.TiltSpeedFast > 0)
{
TiltSpeedFast = (byte)PropertiesConfig.TiltSpeedFast;
}
}
public override bool CustomActivate() public override bool CustomActivate()
{ {
Communication.Connect(); Communication.Connect();
@ -110,40 +195,245 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
Communication.SendBytes(b); Communication.SendBytes(b);
} }
void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e) void Communication_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs e)
{ {
// This is probably not thread-safe buffering var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
// Append the incoming bytes with whatever is in the buffer
var newBytes = new byte[IncomingBuffer.Length + e.Bytes.Length];
IncomingBuffer.CopyTo(newBytes, 0);
e.Bytes.CopyTo(newBytes, IncomingBuffer.Length);
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
Debug.Console(2, this, "Received:{0}", ComTextHelper.GetEscapedText(newBytes));
}
try
{
// This is probably not thread-safe buffering
// Append the incoming bytes with whatever is in the buffer
IncomingBuffer.CopyTo(newBytes, 0);
e.Bytes.CopyTo(newBytes, IncomingBuffer.Length);
if (Debug.Level == 2) // This check is here to prevent following string format from building unnecessarily on level 0 or 1
Debug.Console(2, this, "Received:{0}", ComTextHelper.GetEscapedText(newBytes));
private void SendPanTiltCommand (byte[] cmd) byte[] message = new byte[] { };
// Search for the delimiter 0xFF character
for (int i = 0; i < newBytes.Length; i++)
{
if (newBytes[i] == 0xFF)
{
// i will be the index of the delmiter character
message = newBytes.Take(i).ToArray();
// Skip over what we just took and save the rest for next time
newBytes = newBytes.Skip(i).ToArray();
}
}
if (message.Length > 0)
{
// Check for matching ID
if (message[0] != ResponseID)
{
return;
}
switch (message[1])
{
case 0x40:
{
// ACK received
Debug.Console(2, this, "ACK Received");
break;
}
case 0x50:
{
if (message[2] == 0xFF)
{
// Completion received
Debug.Console(2, this, "Completion Received");
}
else
{
// Inquiry response received. Dequeue the next response handler and invoke it
if (InquiryResponseQueue.Count > 0)
{
var inquiryAction = InquiryResponseQueue.Dequeue();
inquiryAction.Invoke(message.Skip(2).ToArray());
}
else
{
Debug.Console(2, this, "Response Queue is empty. Nothing to dequeue.");
}
}
break;
}
case 0x60:
{
// Error message
switch (message[2])
{
case 0x01:
{
// Message Length Error
Debug.Console(2, this, "Error from device: Message Length Error");
break;
}
case 0x02:
{
// Syntax Error
Debug.Console(2, this, "Error from device: Syntax Error");
break;
}
case 0x03:
{
// Command Buffer Full
Debug.Console(2, this, "Error from device: Command Buffer Full");
break;
}
case 0x04:
{
// Command Cancelled
Debug.Console(2, this, "Error from device: Command Cancelled");
break;
}
case 0x05:
{
// No Socket
Debug.Console(2, this, "Error from device: No Socket");
break;
}
case 0x41:
{
// Command not executable
Debug.Console(2, this, "Error from device: Command not executable");
break;
}
}
break;
}
}
if (message == new byte[] { ResponseID, 0x50, 0x02, 0xFF })
{
PowerIsOn = true;
}
else if (message == new byte[] { ResponseID, 0x50, 0x03, 0xFF })
{
PowerIsOn = false;
}
}
}
catch (Exception err)
{
Debug.Console(2, this, "Error parsing feedback: {0}", err);
}
finally
{
// Save whatever partial message is here
IncomingBuffer = newBytes;
}
}
/// <summary>
/// Sends a pan/tilt command. If the command is not for fastSpeed then it starts a timer to initiate fast speed.
/// </summary>
/// <param name="cmd"></param>
/// <param name="fastSpeed"></param>
private void SendPanTiltCommand (byte[] cmd, bool fastSpeedEnabled)
{ {
var temp = new Byte[] { 0x81, 0x01, 0x06, 0x01, PanSpeed, TiltSpeed }; SendBytes(GetPanTiltCommand(cmd, fastSpeedEnabled));
int length = temp.Length + cmd.Length + 1;
if (!fastSpeedEnabled)
byte[] sum = new byte[length]; {
temp.CopyTo(sum, 0); if (SpeedTimer != null)
cmd.CopyTo(sum, temp.Length); {
sum[length - 1] = 0xFF; StopSpeedTimer();
SendBytes(sum); }
// Start the timer to send fast speed if still moving after FastSpeedHoldTime elapses
SpeedTimer = new CTimer((o) => SendPanTiltCommand(GetPanTiltCommand(cmd, true), true), FastSpeedHoldTimeMs);
}
} }
private void StopSpeedTimer()
{
if (SpeedTimer != null)
{
SpeedTimer.Stop();
SpeedTimer.Dispose();
SpeedTimer = null;
}
}
/// <summary>
/// Generates the pan/tilt command with either slow or fast speed
/// </summary>
/// <param name="cmd"></param>
/// <param name="fastSpeed"></param>
/// <returns></returns>
private byte[] GetPanTiltCommand(byte[] cmd, bool fastSpeed)
{
byte panSpeed;
byte tiltSpeed;
if (!fastSpeed)
{
panSpeed = PanSpeedSlow;
tiltSpeed = TiltSpeedSlow;
}
else
{
panSpeed = PanSpeedFast;
tiltSpeed = TiltSpeedFast;
}
var temp = new byte[] { ID, 0x01, 0x06, 0x01, panSpeed, tiltSpeed };
int length = temp.Length + cmd.Length + 1;
byte[] sum = new byte[length];
temp.CopyTo(sum, 0);
cmd.CopyTo(sum, temp.Length);
sum[length - 1] = 0xFF;
return sum;
}
void SendPowerQuery()
{
SendBytes(new byte[] { ID, 0x09, 0x04, 0x00, 0xFF });
InquiryResponseQueue.Enqueue(HandlePowerResponse);
}
public void PowerOn() public void PowerOn()
{ {
SendBytes(new byte[] { ID, 0x01, 0x04, 0x00, 0x02, 0xFF });
SendBytes(new Byte[] { 0x81, 0x01, 0x04, 0x00, 0x02, 0xFF }); SendPowerQuery();
} }
void HandlePowerResponse(byte[] response)
{
switch (response[0])
{
case 0x02:
{
PowerIsOn = true;
break;
}
case 0x03:
{
PowerIsOn = false;
break;
}
}
}
public void PowerOff() public void PowerOff()
{ {
SendBytes(new Byte[] {0x81, 0x01, 0x04, 0x00, 0x03, 0xFF}); SendBytes(new byte[] {ID, 0x01, 0x04, 0x00, 0x03, 0xFF});
} SendPowerQuery();
}
public void PowerToggle() public void PowerToggle()
{ {
@ -155,12 +445,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
public void PanLeft() public void PanLeft()
{ {
SendPanTiltCommand(new byte[] {0x01, 0x03}); SendPanTiltCommand(new byte[] {0x01, 0x03}, false);
IsMoving = true; IsMoving = true;
} }
public void PanRight() public void PanRight()
{ {
SendPanTiltCommand(new byte[] { 0x02, 0x03 }); SendPanTiltCommand(new byte[] { 0x02, 0x03 }, false);
IsMoving = true; IsMoving = true;
} }
public void PanStop() public void PanStop()
@ -169,12 +459,12 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
} }
public void TiltDown() public void TiltDown()
{ {
SendPanTiltCommand(new byte[] { 0x03, 0x02 }); SendPanTiltCommand(new byte[] { 0x03, 0x02 }, false);
IsMoving = true; IsMoving = true;
} }
public void TiltUp() public void TiltUp()
{ {
SendPanTiltCommand(new byte[] { 0x03, 0x01 }); SendPanTiltCommand(new byte[] { 0x03, 0x01 }, false);
IsMoving = true; IsMoving = true;
} }
public void TiltStop() public void TiltStop()
@ -184,16 +474,18 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
private void SendZoomCommand (byte cmd) private void SendZoomCommand (byte cmd)
{ {
SendBytes(new byte[] {0x81, 0x01, 0x04, 0x07, cmd, 0xFF} ); SendBytes(new byte[] {ID, 0x01, 0x04, 0x07, cmd, 0xFF} );
} }
public void ZoomIn() public void ZoomIn()
{ {
SendZoomCommand(0x02); SendZoomCommand(ZoomInCmd);
IsZooming = true; IsZooming = true;
} }
public void ZoomOut() public void ZoomOut()
{ {
SendZoomCommand(0x03); SendZoomCommand(ZoomOutCmd);
IsZooming = true; IsZooming = true;
} }
public void ZoomStop() public void ZoomStop()
@ -205,26 +497,28 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
{ {
if (IsZooming) if (IsZooming)
{ {
SendZoomCommand(0x00); SendZoomCommand(ZoomStopCmd);
IsZooming = false; IsZooming = false;
} }
else else
{ {
SendPanTiltCommand(new byte[] {0x03, 0x03}); StopSpeedTimer();
SendPanTiltCommand(new byte[] { 0x03, 0x03 }, false);
IsMoving = false; IsMoving = false;
} }
} }
public void PositionHome() public void PositionHome()
{ {
throw new NotImplementedException(); SendBytes(new byte[] { ID, 0x01, 0x06, 0x02, PanSpeedFast, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF });
SendBytes(new byte[] { ID, 0x01, 0x04, 0x47, 0x00, 0x00, 0x00, 0x00, 0xFF });
} }
public void RecallPreset(int presetNumber) public void RecallPreset(int presetNumber)
{ {
SendBytes(new byte[] {0x81, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF} ); SendBytes(new byte[] {ID, 0x01, 0x04, 0x3F, 0x02, (byte)presetNumber, 0xFF} );
} }
public void SavePreset(int presetNumber) public void SavePreset(int presetNumber)
{ {
SendBytes(new byte[] { 0x81, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF }); SendBytes(new byte[] { ID, 0x01, 0x04, 0x3F, 0x01, (byte)presetNumber, 0xFF });
} }
#region IHasCameraPresets Members #region IHasCameraPresets Members
@ -244,6 +538,90 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
} }
#endregion #endregion
#region IHasCameraFocusControl Members
public void FocusNear()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x08, 0x03, 0xFF });
}
public void FocusFar()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x08, 0x02, 0xFF });
}
public void FocusStop()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x08, 0x00, 0xFF });
}
public void TriggerAutoFocus()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x18, 0x01, 0xFF });
SendAutoFocusQuery();
}
#endregion
#region IHasAutoFocus Members
public void SetFocusModeAuto()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x38, 0x02, 0xFF });
SendAutoFocusQuery();
}
public void SetFocusModeManual()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x38, 0x03, 0xFF });
SendAutoFocusQuery();
}
public void ToggleFocusMode()
{
SendBytes(new byte[] { ID, 0x01, 0x04, 0x38, 0x10, 0xFF });
SendAutoFocusQuery();
}
#endregion
void SendAutoFocusQuery()
{
SendBytes(new byte[] { ID, 0x09, 0x04, 0x38, 0xFF });
InquiryResponseQueue.Enqueue(HandleAutoFocusResponse);
}
void HandleAutoFocusResponse(byte[] response)
{
switch (response[0])
{
case 0x02:
{
// Auto Mode
PowerIsOn = true;
break;
}
case 0x03:
{
// Manual Mode
PowerIsOn = false;
break;
}
}
}
#region IHasCameraOff Members
public BoolFeedback CameraIsOffFeedback { get; private set; }
public void CameraOff()
{
PowerOff();
}
#endregion
} }
public class CameraViscaFactory : EssentialsDeviceFactory<CameraVisca> public class CameraViscaFactory : EssentialsDeviceFactory<CameraVisca>
@ -257,10 +635,51 @@ namespace PepperDash.Essentials.Devices.Common.Cameras
{ {
Debug.Console(1, "Factory Attempting to create new CameraVisca Device"); Debug.Console(1, "Factory Attempting to create new CameraVisca Device");
var comm = CommFactory.CreateCommForDevice(dc); var comm = CommFactory.CreateCommForDevice(dc);
var props = Newtonsoft.Json.JsonConvert.DeserializeObject<Cameras.CameraPropertiesConfig>( var props = Newtonsoft.Json.JsonConvert.DeserializeObject<Cameras.CameraViscaPropertiesConfig>(
dc.Properties.ToString()); dc.Properties.ToString());
return new Cameras.CameraVisca(dc.Key, dc.Name, comm, props); return new Cameras.CameraVisca(dc.Key, dc.Name, comm, props);
} }
} }
public class CameraViscaPropertiesConfig : CameraPropertiesConfig
{
/// <summary>
/// Control ID of the camera (1-7)
/// </summary>
[JsonProperty("id")]
public uint Id { get; set; }
/// <summary>
/// Slow Pan speed (0-18)
/// </summary>
[JsonProperty("panSpeedSlow")]
public uint PanSpeedSlow { get; set; }
/// <summary>
/// Fast Pan speed (0-18)
/// </summary>
[JsonProperty("panSpeedFast")]
public uint PanSpeedFast { get; set; }
/// <summary>
/// Slow tilt speed (0-18)
/// </summary>
[JsonProperty("tiltSpeedSlow")]
public uint TiltSpeedSlow { get; set; }
/// <summary>
/// Fast tilt speed (0-18)
/// </summary>
[JsonProperty("tiltSpeedFast")]
public uint TiltSpeedFast { get; set; }
/// <summary>
/// Time a button must be held before fast speed is engaged (Milliseconds)
/// </summary>
[JsonProperty("fastSpeedHoldTimeMs")]
public uint FastSpeedHoldTimeMs { get; set; }
}
} }

View file

@ -11,9 +11,11 @@ namespace PepperDash.Essentials.Devices.Common.Codec
public interface IHasExternalSourceSwitching public interface IHasExternalSourceSwitching
{ {
bool ExternalSourceListEnabled { get; } bool ExternalSourceListEnabled { get; }
string ExternalSourceInputPort { get; }
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type); void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
void SetExternalSourceState(string key, eExternalSourceMode mode); void SetExternalSourceState(string key, eExternalSourceMode mode);
void ClearExternalSources(); void ClearExternalSources();
void SetSelectedSource(string key);
Action<string, string> RunRouteAction { set;} Action<string, string> RunRouteAction { set;}
} }

View file

@ -10,26 +10,28 @@ using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Displays namespace PepperDash.Essentials.Devices.Displays
{ {
public abstract class ComTcpDisplayBase : DisplayBase, IPower [Obsolete("Please use TwoWayDisplayBase instead")]
public abstract class ComTcpDisplayBase : TwoWayDisplayBase
{ {
/// <summary>
/// Sets the communication method for this - swaps out event handlers and output handlers ///// <summary>
/// </summary> ///// Sets the communication method for this - swaps out event handlers and output handlers
public IBasicCommunication CommunicationMethod ///// </summary>
{ //public IBasicCommunication CommunicationMethod
get { return _CommunicationMethod; } //{
set // get { return _CommunicationMethod; }
{ // set
if (_CommunicationMethod != null) // {
_CommunicationMethod.BytesReceived -= this.CommunicationMethod_BytesReceived; // if (_CommunicationMethod != null)
// Outputs??? // _CommunicationMethod.BytesReceived -= this.CommunicationMethod_BytesReceived;
_CommunicationMethod = value; // // Outputs???
if (_CommunicationMethod != null) // _CommunicationMethod = value;
_CommunicationMethod.BytesReceived += this.CommunicationMethod_BytesReceived; // if (_CommunicationMethod != null)
// Outputs? // _CommunicationMethod.BytesReceived += this.CommunicationMethod_BytesReceived;
} // // Outputs?
} // }
IBasicCommunication _CommunicationMethod; //}
//IBasicCommunication _CommunicationMethod;
public ComTcpDisplayBase(string key, string name) public ComTcpDisplayBase(string key, string name)
: base(key, name) : base(key, name)
@ -38,6 +40,6 @@ namespace PepperDash.Essentials.Devices.Displays
} }
protected abstract void CommunicationMethod_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args); //protected abstract void CommunicationMethod_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args);
} }
} }

View file

@ -11,217 +11,222 @@ using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.Devices.Displays namespace PepperDash.Essentials.Devices.Displays
{ {
public class NecPaSeriesProjector : ComTcpDisplayBase, IBridgeAdvanced //public class NecPaSeriesProjector : TwoWayDisplayBase, IBridgeAdvanced
{ //{
public readonly IntFeedback Lamp1RemainingPercent; // public readonly IntFeedback Lamp1RemainingPercent;
int _Lamp1RemainingPercent; // int _Lamp1RemainingPercent;
public readonly IntFeedback Lamp2RemainingPercent; // public readonly IntFeedback Lamp2RemainingPercent;
int _Lamp2RemainingPercent; // int _Lamp2RemainingPercent;
protected override Func<bool> PowerIsOnFeedbackFunc
{
get { return () => _PowerIsOn; }
}
bool _PowerIsOn;
protected override Func<bool> IsCoolingDownFeedbackFunc // RoutingInputPort _CurrentInputPort;
{
get { return () => false; }
}
protected override Func<bool> IsWarmingUpFeedbackFunc // protected override Func<string> CurrentInputFeedbackFunc { get { return () => _CurrentInputPort.Key; } }
{
get { return () => false; } // protected override Func<bool> PowerIsOnFeedbackFunc
} // {
// get { return () => _PowerIsOn; }
// }
// bool _PowerIsOn;
public override void PowerToggle() // protected override Func<bool> IsCoolingDownFeedbackFunc
{ // {
throw new NotImplementedException(); // get { return () => false; }
} // }
public override void ExecuteSwitch(object selector) // protected override Func<bool> IsWarmingUpFeedbackFunc
{ // {
throw new NotImplementedException(); // get { return () => false; }
} // }
Dictionary<string, string> InputMap; // public override void PowerToggle()
// {
// throw new NotImplementedException();
// }
/// <summary> // public override void ExecuteSwitch(object selector)
/// Constructor // {
/// </summary> // throw new NotImplementedException();
public NecPaSeriesProjector(string key, string name) // }
: base(key, name)
{
Lamp1RemainingPercent = new IntFeedback("Lamp1RemainingPercent", () => _Lamp1RemainingPercent);
Lamp2RemainingPercent = new IntFeedback("Lamp2RemainingPercent", () => _Lamp2RemainingPercent);
InputMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) // Dictionary<string, string> InputMap;
{
{ "computer1", "\x02\x03\x00\x00\x02\x01\x01\x09" },
{ "computer2", "\x02\x03\x00\x00\x02\x01\x02\x0a" },
{ "computer3", "\x02\x03\x00\x00\x02\x01\x03\x0b" },
{ "hdmi", "\x02\x03\x00\x00\x02\x01\x1a\x22" },
{ "dp", "\x02\x03\x00\x00\x02\x01\x1b\x23" },
{ "video", "\x02\x03\x00\x00\x02\x01\x06\x0e" },
{ "viewer", "\x02\x03\x00\x00\x02\x01\x1f\x27" },
{ "network", "\x02\x03\x00\x00\x02\x01\x20\x28" },
};
}
void IsConnected_OutputChange(object sender, EventArgs e) // /// <summary>
{ // /// Constructor
// /// </summary>
// public NecPaSeriesProjector(string key, string name)
// : base(key, name)
// {
// Lamp1RemainingPercent = new IntFeedback("Lamp1RemainingPercent", () => _Lamp1RemainingPercent);
// Lamp2RemainingPercent = new IntFeedback("Lamp2RemainingPercent", () => _Lamp2RemainingPercent);
} // InputMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
// {
// { "computer1", "\x02\x03\x00\x00\x02\x01\x01\x09" },
// { "computer2", "\x02\x03\x00\x00\x02\x01\x02\x0a" },
// { "computer3", "\x02\x03\x00\x00\x02\x01\x03\x0b" },
// { "hdmi", "\x02\x03\x00\x00\x02\x01\x1a\x22" },
// { "dp", "\x02\x03\x00\x00\x02\x01\x1b\x23" },
// { "video", "\x02\x03\x00\x00\x02\x01\x06\x0e" },
// { "viewer", "\x02\x03\x00\x00\x02\x01\x1f\x27" },
// { "network", "\x02\x03\x00\x00\x02\x01\x20\x28" },
// };
// }
public void SetEnable(bool state) // void IsConnected_OutputChange(object sender, EventArgs e)
{ // {
var tcp = CommunicationMethod as GenericTcpIpClient;
if (tcp != null)
{
tcp.Connect();
}
}
public override void PowerOn() // }
{
SendText("\x02\x00\x00\x00\x00\x02");
}
public override void PowerOff() // public void SetEnable(bool state)
{ // {
SendText("\x02\x01\x00\x00\x00\x03"); // var tcp = CommunicationMethod as GenericTcpIpClient;
} // if (tcp != null)
// {
// tcp.Connect();
// }
// }
public void PictureMuteOn() // public override void PowerOn()
{ // {
SendText("\x02\x10\x00\x00\x00\x12"); // SendText("\x02\x00\x00\x00\x00\x02");
} // }
public void PictureMuteOff() // public override void PowerOff()
{ // {
SendText("\x02\x11\x00\x00\x00\x13"); // SendText("\x02\x01\x00\x00\x00\x03");
} // }
public void GetRunningStatus() // public void PictureMuteOn()
{ // {
SendText("\x00\x85\x00\x00\x01\x01\x87"); // SendText("\x02\x10\x00\x00\x00\x12");
} // }
public void GetLampRemaining(int lampNum) // public void PictureMuteOff()
{ // {
if (!_PowerIsOn) return; // SendText("\x02\x11\x00\x00\x00\x13");
// }
var bytes = new byte[]{0x03,0x96,0x00,0x00,0x02,0x00,0x04}; // public void GetRunningStatus()
if (lampNum == 2) // {
bytes[5] = 0x01; // SendText("\x00\x85\x00\x00\x01\x01\x87");
SendBytes(AppendChecksum(bytes)); // }
}
public void SelectInput(string inputKey) // public void GetLampRemaining(int lampNum)
{ // {
if (InputMap.ContainsKey(inputKey)) // if (!_PowerIsOn) return;
SendText(InputMap[inputKey]);
}
void SendText(string text) // var bytes = new byte[]{0x03,0x96,0x00,0x00,0x02,0x00,0x04};
{ // if (lampNum == 2)
if (CommunicationMethod != null) // bytes[5] = 0x01;
CommunicationMethod.SendText(text); // SendBytes(AppendChecksum(bytes));
} // }
void SendBytes(byte[] bytes) // public void SelectInput(string inputKey)
{ // {
if (CommunicationMethod != null) // if (InputMap.ContainsKey(inputKey))
CommunicationMethod.SendBytes(bytes); // SendText(InputMap[inputKey]);
} // }
byte[] AppendChecksum(byte[] bytes) // void SendText(string text)
{ // {
byte sum = unchecked((byte)bytes.Sum(x => (int)x)); // if (CommunicationMethod != null)
var retVal = new byte[bytes.Length + 1]; // CommunicationMethod.SendText(text);
bytes.CopyTo(retVal, 0); // }
retVal[retVal.Length - 1] = sum;
return retVal;
}
protected override void CommunicationMethod_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args) // void SendBytes(byte[] bytes)
{ // {
var bytes = args.Bytes; // if (CommunicationMethod != null)
ParseBytes(args.Bytes); // CommunicationMethod.SendBytes(bytes);
} // }
void ParseBytes(byte[] bytes) // byte[] AppendChecksum(byte[] bytes)
{ // {
if (bytes[0] == 0x22) // byte sum = unchecked((byte)bytes.Sum(x => (int)x));
{ // var retVal = new byte[bytes.Length + 1];
// Power on // bytes.CopyTo(retVal, 0);
if (bytes[1] == 0x00) // retVal[retVal.Length - 1] = sum;
{ // return retVal;
_PowerIsOn = true; // }
PowerIsOnFeedback.FireUpdate();
}
// Power off
else if (bytes[1] == 0x01)
{
_PowerIsOn = false;
PowerIsOnFeedback.FireUpdate();
}
}
// Running Status
else if (bytes[0] == 0x20 && bytes[1] == 0x85 && bytes[4] == 0x10)
{
var operationStates = new Dictionary<int, string>
{
{ 0x00, "Standby" },
{ 0x04, "Power On" },
{ 0x05, "Cooling" },
{ 0x06, "Standby (error)" },
{ 0x0f, "Standby (power saving" },
{ 0x10, "Network Standby" },
{ 0xff, "Not supported" }
};
var newPowerIsOn = bytes[7] == 0x01; // protected override void CommunicationMethod_BytesReceived(object sender, GenericCommMethodReceiveBytesArgs args)
if (newPowerIsOn != _PowerIsOn) // {
{ // var bytes = args.Bytes;
_PowerIsOn = newPowerIsOn; // ParseBytes(args.Bytes);
PowerIsOnFeedback.FireUpdate(); // }
}
Debug.Console(2, this, "PowerIsOn={0}\rCooling={1}\rPowering on/off={2}\rStatus={3}", // void ParseBytes(byte[] bytes)
_PowerIsOn, // {
bytes[8] == 0x01, // if (bytes[0] == 0x22)
bytes[9] == 0x01, // {
operationStates[bytes[10]]); // // Power on
// if (bytes[1] == 0x00)
// {
// _PowerIsOn = true;
// PowerIsOnFeedback.FireUpdate();
// }
// // Power off
// else if (bytes[1] == 0x01)
// {
// _PowerIsOn = false;
// PowerIsOnFeedback.FireUpdate();
// }
// }
// // Running Status
// else if (bytes[0] == 0x20 && bytes[1] == 0x85 && bytes[4] == 0x10)
// {
// var operationStates = new Dictionary<int, string>
// {
// { 0x00, "Standby" },
// { 0x04, "Power On" },
// { 0x05, "Cooling" },
// { 0x06, "Standby (error)" },
// { 0x0f, "Standby (power saving" },
// { 0x10, "Network Standby" },
// { 0xff, "Not supported" }
// };
// var newPowerIsOn = bytes[7] == 0x01;
// if (newPowerIsOn != _PowerIsOn)
// {
// _PowerIsOn = newPowerIsOn;
// PowerIsOnFeedback.FireUpdate();
// }
// Debug.Console(2, this, "PowerIsOn={0}\rCooling={1}\rPowering on/off={2}\rStatus={3}",
// _PowerIsOn,
// bytes[8] == 0x01,
// bytes[9] == 0x01,
// operationStates[bytes[10]]);
} // }
// Lamp remaining // // Lamp remaining
else if (bytes[0] == 0x23 && bytes[1] == 0x96 && bytes[4] == 0x06 && bytes[6] == 0x04) // else if (bytes[0] == 0x23 && bytes[1] == 0x96 && bytes[4] == 0x06 && bytes[6] == 0x04)
{ // {
var newValue = bytes[7]; // var newValue = bytes[7];
if (bytes[5] == 0x00) // if (bytes[5] == 0x00)
{ // {
if (newValue != _Lamp1RemainingPercent) // if (newValue != _Lamp1RemainingPercent)
{ // {
_Lamp1RemainingPercent = newValue; // _Lamp1RemainingPercent = newValue;
Lamp1RemainingPercent.FireUpdate(); // Lamp1RemainingPercent.FireUpdate();
} // }
} // }
else // else
{ // {
if (newValue != _Lamp2RemainingPercent) // if (newValue != _Lamp2RemainingPercent)
{ // {
_Lamp2RemainingPercent = newValue; // _Lamp2RemainingPercent = newValue;
Lamp2RemainingPercent.FireUpdate(); // Lamp2RemainingPercent.FireUpdate();
} // }
} // }
Debug.Console(0, this, "Lamp {0}, {1}% remaining", (bytes[5] + 1), bytes[7]); // Debug.Console(0, this, "Lamp {0}, {1}% remaining", (bytes[5] + 1), bytes[7]);
} // }
} // }
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) // public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{ // {
LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge); // LinkDisplayToApi(this, trilist, joinStart, joinMapKey, bridge);
} // }
} //}
} }

View file

@ -63,7 +63,7 @@
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll</HintPath> <HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll</HintPath>
</Reference> </Reference>
<Reference Include="mscorlib" /> <Reference Include="mscorlib" />
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath> <HintPath>..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
</Reference> </Reference>

View file

@ -16,12 +16,12 @@ using PepperDash.Essentials.Core.Routing;
namespace PepperDash.Essentials.Devices.Common namespace PepperDash.Essentials.Devices.Common
{ {
[Description("Wrapper class for an IR Set Top Box")] [Description("Wrapper class for an IR Set Top Box")]
public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IPower public class IRSetTopBoxBase : EssentialsBridgeableDevice, ISetTopBoxControls, IRoutingOutputs, IUsageTracking, IHasPowerControl
{ {
public IrOutputPortController IrPort { get; private set; } public IrOutputPortController IrPort { get; private set; }
public uint DisplayUiType { get { return DisplayUiConstants.TypeDirecTv; } } public uint DisplayUiType { get { return DisplayUiConstants.TypeDirecTv; } }
public ushort IrPulseTime { get; set; }
public bool HasPresets { get; set; } public bool HasPresets { get; set; }
public bool HasDvr { get; set; } public bool HasDvr { get; set; }
@ -35,6 +35,13 @@ namespace PepperDash.Essentials.Devices.Common
: base(key, name) : base(key, name)
{ {
IrPort = portCont; IrPort = portCont;
IrPulseTime = 200;
if (props.IrPulseTime > 0)
{
IrPulseTime = (ushort)props.IrPulseTime;
}
DeviceManager.AddDevice(portCont); DeviceManager.AddDevice(portCont);
HasPresets = props.HasPresets; HasPresets = props.HasPresets;
@ -55,7 +62,6 @@ namespace PepperDash.Essentials.Devices.Common
AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio, AnyAudioOut = new RoutingOutputPort(RoutingPortNames.AnyAudioOut, eRoutingSignalType.Audio,
eRoutingPortConnectionType.DigitalAudio, null, this); eRoutingPortConnectionType.DigitalAudio, null, this);
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyVideoOut, AnyAudioOut }; OutputPorts = new RoutingPortCollection<RoutingOutputPort> { AnyVideoOut, AnyAudioOut };
} }
public void LoadPresets(string filePath) public void LoadPresets(string filePath)
@ -348,26 +354,17 @@ namespace PepperDash.Essentials.Devices.Common
public void PowerOn() public void PowerOn()
{ {
IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_ON, true); IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_ON, false);
} }
public void PowerOff() public void PowerOff()
{ {
IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_OFF, true); IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
IrPort.PressRelease(IROutputStandardCommands.IROut_POWER_OFF, false);
} }
public void PowerToggle() public void PowerToggle()
{ {
throw new NotImplementedException(); IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
}
public BoolFeedback PowerIsOnFeedback
{
get { throw new NotImplementedException(); }
} }
#endregion #endregion
@ -395,79 +392,96 @@ namespace PepperDash.Essentials.Devices.Common
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name; trilist.StringInput[joinMap.Name.JoinNumber].StringValue = Name;
var stbBase = this as ISetTopBoxControls; var stbBase = this as ISetTopBoxControls;
if (stbBase != null)
{
trilist.BooleanInput[joinMap.HasDpad.JoinNumber].BoolValue = stbBase.HasDpad;
trilist.BooleanInput[joinMap.HasNumeric.JoinNumber].BoolValue = stbBase.HasNumeric;
trilist.BooleanInput[joinMap.HasDvr.JoinNumber].BoolValue = stbBase.HasDvr;
trilist.BooleanInput[joinMap.HasPresets.JoinNumber].BoolValue = stbBase.HasPresets;
trilist.BooleanInput[joinMap.HasDpad.JoinNumber].BoolValue = stbBase.HasDpad; trilist.SetBoolSigAction(joinMap.DvrList.JoinNumber, stbBase.DvrList);
trilist.BooleanInput[joinMap.HasNumeric.JoinNumber].BoolValue = stbBase.HasNumeric; trilist.SetBoolSigAction(joinMap.Replay.JoinNumber, stbBase.Replay);
trilist.BooleanInput[joinMap.HasDvr.JoinNumber].BoolValue = stbBase.HasDvr;
trilist.BooleanInput[joinMap.HasPresets.JoinNumber].BoolValue = stbBase.HasPresets;
trilist.SetBoolSigAction(joinMap.DvrList.JoinNumber, stbBase.DvrList); trilist.SetStringSigAction(joinMap.LoadPresets.JoinNumber, stbBase.LoadPresets);
trilist.SetBoolSigAction(joinMap.Replay.JoinNumber, stbBase.Replay); }
trilist.SetStringSigAction(joinMap.LoadPresets.JoinNumber, stbBase.LoadPresets); var stbPower = this as IHasPowerControl;
if (stbPower != null)
var stbPower = this as IPower; {
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, stbPower.PowerOn);
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, stbPower.PowerOn); trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, stbPower.PowerOff);
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, stbPower.PowerOff); trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, stbPower.PowerToggle);
trilist.SetSigTrueAction(joinMap.PowerToggle.JoinNumber, stbPower.PowerToggle); }
var stbDPad = this as IDPad; var stbDPad = this as IDPad;
if (stbDPad != null)
trilist.SetBoolSigAction(joinMap.Up.JoinNumber, stbDPad.Up); {
trilist.SetBoolSigAction(joinMap.Down.JoinNumber, stbDPad.Down); trilist.SetBoolSigAction(joinMap.Up.JoinNumber, stbDPad.Up);
trilist.SetBoolSigAction(joinMap.Left.JoinNumber, stbDPad.Left); trilist.SetBoolSigAction(joinMap.Down.JoinNumber, stbDPad.Down);
trilist.SetBoolSigAction(joinMap.Right.JoinNumber, stbDPad.Right); trilist.SetBoolSigAction(joinMap.Left.JoinNumber, stbDPad.Left);
trilist.SetBoolSigAction(joinMap.Select.JoinNumber, stbDPad.Select); trilist.SetBoolSigAction(joinMap.Right.JoinNumber, stbDPad.Right);
trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, stbDPad.Menu); trilist.SetBoolSigAction(joinMap.Select.JoinNumber, stbDPad.Select);
trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbDPad.Exit); trilist.SetBoolSigAction(joinMap.Menu.JoinNumber, stbDPad.Menu);
trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbDPad.Exit);
}
var stbChannel = this as IChannel; var stbChannel = this as IChannel;
trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, stbChannel.ChannelUp); if (stbChannel != null)
trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, stbChannel.ChannelDown); {
trilist.SetBoolSigAction(joinMap.LastChannel.JoinNumber, stbChannel.LastChannel); trilist.SetBoolSigAction(joinMap.ChannelUp.JoinNumber, stbChannel.ChannelUp);
trilist.SetBoolSigAction(joinMap.Guide.JoinNumber, stbChannel.Guide); trilist.SetBoolSigAction(joinMap.ChannelDown.JoinNumber, stbChannel.ChannelDown);
trilist.SetBoolSigAction(joinMap.Info.JoinNumber, stbChannel.Info); trilist.SetBoolSigAction(joinMap.LastChannel.JoinNumber, stbChannel.LastChannel);
trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbChannel.Exit); trilist.SetBoolSigAction(joinMap.Guide.JoinNumber, stbChannel.Guide);
trilist.SetBoolSigAction(joinMap.Info.JoinNumber, stbChannel.Info);
trilist.SetBoolSigAction(joinMap.Exit.JoinNumber, stbChannel.Exit);
}
var stbColor = this as IColor; var stbColor = this as IColor;
trilist.SetBoolSigAction(joinMap.Red.JoinNumber, stbColor.Red); if (stbColor != null)
trilist.SetBoolSigAction(joinMap.Green.JoinNumber, stbColor.Green); {
trilist.SetBoolSigAction(joinMap.Yellow.JoinNumber, stbColor.Yellow); trilist.SetBoolSigAction(joinMap.Red.JoinNumber, stbColor.Red);
trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, stbColor.Blue); trilist.SetBoolSigAction(joinMap.Green.JoinNumber, stbColor.Green);
trilist.SetBoolSigAction(joinMap.Yellow.JoinNumber, stbColor.Yellow);
trilist.SetBoolSigAction(joinMap.Blue.JoinNumber, stbColor.Blue);
}
var stbKeypad = this as ISetTopBoxNumericKeypad; var stbKeypad = this as ISetTopBoxNumericKeypad;
if (stbKeypad != null)
{
trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton1Label;
trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton2Label;
trilist.StringInput[joinMap.KeypadAccessoryButton1Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton1Label; trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton1;
trilist.StringInput[joinMap.KeypadAccessoryButton2Label.JoinNumber].StringValue = stbKeypad.KeypadAccessoryButton2Label; trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton2;
trilist.BooleanInput[joinMap.HasKeypadAccessoryButton1.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton1; trilist.SetBoolSigAction(joinMap.Digit0.JoinNumber, stbKeypad.Digit0);
trilist.BooleanInput[joinMap.HasKeypadAccessoryButton2.JoinNumber].BoolValue = stbKeypad.HasKeypadAccessoryButton2; trilist.SetBoolSigAction(joinMap.Digit1.JoinNumber, stbKeypad.Digit1);
trilist.SetBoolSigAction(joinMap.Digit2.JoinNumber, stbKeypad.Digit2);
trilist.SetBoolSigAction(joinMap.Digit0.JoinNumber, stbKeypad.Digit0); trilist.SetBoolSigAction(joinMap.Digit3.JoinNumber, stbKeypad.Digit3);
trilist.SetBoolSigAction(joinMap.Digit1.JoinNumber, stbKeypad.Digit1); trilist.SetBoolSigAction(joinMap.Digit4.JoinNumber, stbKeypad.Digit4);
trilist.SetBoolSigAction(joinMap.Digit2.JoinNumber, stbKeypad.Digit2); trilist.SetBoolSigAction(joinMap.Digit5.JoinNumber, stbKeypad.Digit5);
trilist.SetBoolSigAction(joinMap.Digit3.JoinNumber, stbKeypad.Digit3); trilist.SetBoolSigAction(joinMap.Digit6.JoinNumber, stbKeypad.Digit6);
trilist.SetBoolSigAction(joinMap.Digit4.JoinNumber, stbKeypad.Digit4); trilist.SetBoolSigAction(joinMap.Digit7.JoinNumber, stbKeypad.Digit7);
trilist.SetBoolSigAction(joinMap.Digit5.JoinNumber, stbKeypad.Digit5); trilist.SetBoolSigAction(joinMap.Digit8.JoinNumber, stbKeypad.Digit8);
trilist.SetBoolSigAction(joinMap.Digit6.JoinNumber, stbKeypad.Digit6); trilist.SetBoolSigAction(joinMap.Digit9.JoinNumber, stbKeypad.Digit9);
trilist.SetBoolSigAction(joinMap.Digit7.JoinNumber, stbKeypad.Digit7); trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press.JoinNumber, stbKeypad.KeypadAccessoryButton1);
trilist.SetBoolSigAction(joinMap.Digit8.JoinNumber, stbKeypad.Digit8); trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press.JoinNumber, stbKeypad.KeypadAccessoryButton1);
trilist.SetBoolSigAction(joinMap.Digit9.JoinNumber, stbKeypad.Digit9); trilist.SetBoolSigAction(joinMap.Dash.JoinNumber, stbKeypad.Dash);
trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton1Press.JoinNumber, stbKeypad.KeypadAccessoryButton1); trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, stbKeypad.KeypadEnter);
trilist.SetBoolSigAction(joinMap.KeypadAccessoryButton2Press.JoinNumber, stbKeypad.KeypadAccessoryButton1); }
trilist.SetBoolSigAction(joinMap.Dash.JoinNumber, stbKeypad.Dash);
trilist.SetBoolSigAction(joinMap.KeypadEnter.JoinNumber, stbKeypad.KeypadEnter);
var stbTransport = this as ITransport; var stbTransport = this as ITransport;
trilist.SetBoolSigAction(joinMap.Play.JoinNumber, stbTransport.Play); if (stbTransport != null)
trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, stbTransport.Pause); {
trilist.SetBoolSigAction(joinMap.Rewind.JoinNumber, stbTransport.Rewind); trilist.SetBoolSigAction(joinMap.Play.JoinNumber, stbTransport.Play);
trilist.SetBoolSigAction(joinMap.FFwd.JoinNumber, stbTransport.FFwd); trilist.SetBoolSigAction(joinMap.Pause.JoinNumber, stbTransport.Pause);
trilist.SetBoolSigAction(joinMap.ChapMinus.JoinNumber, stbTransport.ChapMinus); trilist.SetBoolSigAction(joinMap.Rewind.JoinNumber, stbTransport.Rewind);
trilist.SetBoolSigAction(joinMap.ChapPlus.JoinNumber, stbTransport.ChapPlus); trilist.SetBoolSigAction(joinMap.FFwd.JoinNumber, stbTransport.FFwd);
trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, stbTransport.Stop); trilist.SetBoolSigAction(joinMap.ChapMinus.JoinNumber, stbTransport.ChapMinus);
trilist.SetBoolSigAction(joinMap.Record.JoinNumber, stbTransport.Record); trilist.SetBoolSigAction(joinMap.ChapPlus.JoinNumber, stbTransport.ChapPlus);
trilist.SetBoolSigAction(joinMap.Stop.JoinNumber, stbTransport.Stop);
trilist.SetBoolSigAction(joinMap.Record.JoinNumber, stbTransport.Record);
}
} }
} }

View file

@ -14,6 +14,7 @@ namespace PepperDash.Essentials.Devices.Common
public bool HasDvr { get; set; } public bool HasDvr { get; set; }
public bool HasDpad { get; set; } public bool HasDpad { get; set; }
public bool HasNumeric { get; set; } public bool HasNumeric { get; set; }
public int IrPulseTime { get; set; }
public ControlPropertiesConfig Control { get; set; } public ControlPropertiesConfig Control { get; set; }
} }

View file

@ -106,8 +106,8 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase)) if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
{ {
dest.ReleaseRoute(); dest.ReleaseRoute();
if (dest is IPower) if (dest is IHasPowerControl)
(dest as IPower).PowerOff(); (dest as IHasPowerControl).PowerOff();
} }
else else
{ {

View file

@ -407,6 +407,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CreateOsdSource(); CreateOsdSource();
ExternalSourceListEnabled = props.ExternalSourceListEnabled; ExternalSourceListEnabled = props.ExternalSourceListEnabled;
ExternalSourceInputPort = props.ExternalSourceInputPort;
if (props.UiBranding == null) if (props.UiBranding == null)
{ {
@ -416,6 +417,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
props.UiBranding.BrandingUrl); props.UiBranding.BrandingUrl);
BrandingEnabled = props.UiBranding.Enable; BrandingEnabled = props.UiBranding.Enable;
_brandingUrl = props.UiBranding.BrandingUrl; _brandingUrl = props.UiBranding.BrandingUrl;
} }
@ -1339,10 +1341,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public override void SendDtmf(string s) public override void SendDtmf(string s)
{ {
if (CallFavorites != null) SendText(string.Format("xCommand Call DTMFSend CallId: {0} DTMFString: \"{1}\"", GetCallId(), s));
{
SendText(string.Format("xCommand Call DTMFSend CallId: {0} DTMFString: \"{1}\"", GetCallId(), s));
}
} }
public void SelectPresentationSource(int source) public void SelectPresentationSource(int source)
@ -1920,7 +1919,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
#region IHasExternalSourceSwitching Members #region IHasExternalSourceSwitching Members
/// <summary> /// <summary>
/// Weather the Cisco supports External Source Lists or not /// Wheather the Cisco supports External Source Lists or not
/// </summary> /// </summary>
public bool ExternalSourceListEnabled public bool ExternalSourceListEnabled
{ {
@ -1928,6 +1927,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
private set; private set;
} }
/// <summary>
/// The name of the RoutingInputPort to which the upstream external switcher is connected
/// </summary>
public string ExternalSourceInputPort { get; private set; }
public bool BrandingEnabled { get; private set; } public bool BrandingEnabled { get; private set; }
private string _brandingUrl; private string _brandingUrl;
private bool _sendMcUrl; private bool _sendMcUrl;
@ -1970,6 +1974,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
} }
/// <summary>
/// Sets the selected source of the available external sources on teh Touch10 UI
/// </summary>
public void SetSelectedSource(string key)
{
SendText(string.Format("xCommand UserInterface Presentation ExternalSource Select SourceIdentifier: {0}", key));
}
/// <summary> /// <summary>
/// Action that will run when the External Source is selected. /// Action that will run when the External Source is selected.
/// </summary> /// </summary>
@ -2097,7 +2109,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
public CiscoSparkCodecFactory() public CiscoSparkCodecFactory()
{ {
TypeNames = new List<string>() { "ciscospark", "ciscowebex", "ciscowebexpro", "ciscoroomkit" }; TypeNames = new List<string>() { "ciscospark", "ciscowebex", "ciscowebexpro", "ciscoroomkit", "ciscosparkpluscodec" };
} }
public override EssentialsDevice BuildDevice(DeviceConfig dc) public override EssentialsDevice BuildDevice(DeviceConfig dc)

View file

@ -31,9 +31,18 @@ namespace PepperDash.Essentials.Devices.Common.Codec
[JsonProperty("sharing")] [JsonProperty("sharing")]
public SharingProperties Sharing { get; set; } public SharingProperties Sharing { get; set; }
/// <summary>
/// Enables external source switching capability
/// </summary>
[JsonProperty("externalSourceListEnabled")] [JsonProperty("externalSourceListEnabled")]
public bool ExternalSourceListEnabled { get; set; } public bool ExternalSourceListEnabled { get; set; }
/// <summary>
/// The name of the routing input port on the codec to which the external switch is connected
/// </summary>
[JsonProperty("externalSourceInputPort")]
public string ExternalSourceInputPort { get; set; }
/// <summary> /// <summary>
/// Optionsal property to set the limit of any phonebook queries for directory or searching /// Optionsal property to set the limit of any phonebook queries for directory or searching
/// </summary> /// </summary>

View file

@ -1,131 +1,131 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
/// <summary> /// <summary>
/// This class exists to capture serialized data sent back by a Cisco codec in JSON output mode /// This class exists to capture serialized data sent back by a Cisco codec in JSON output mode
/// </summary> /// </summary>
public class CiscoCodecEvents public class CiscoCodecEvents
{ {
public class CauseValue public class CauseValue
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CauseType public class CauseType
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CauseString public class CauseString
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class OrigCallDirection public class OrigCallDirection
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class RemoteURI public class RemoteURI
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class DisplayName public class DisplayName
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CallId public class CallId
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CauseCode public class CauseCode
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CauseOrigin public class CauseOrigin
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class Protocol public class Protocol
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class Duration public class Duration
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CallType public class CallType
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CallRate public class CallRate
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class Encryption public class Encryption
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class RequestedURI public class RequestedURI
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class PeopleCountAverage public class PeopleCountAverage
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class CallDisconnect public class CallDisconnect
{ {
public string id { get; set; } public string id { get; set; }
public CauseValue CauseValue { get; set; } public CauseValue CauseValue { get; set; }
public CauseType CauseType { get; set; } public CauseType CauseType { get; set; }
public CauseString CauseString { get; set; } public CauseString CauseString { get; set; }
public OrigCallDirection OrigCallDirection { get; set; } public OrigCallDirection OrigCallDirection { get; set; }
public RemoteURI RemoteURI { get; set; } public RemoteURI RemoteURI { get; set; }
public DisplayName DisplayName { get; set; } public DisplayName DisplayName { get; set; }
public CallId CallId { get; set; } public CallId CallId { get; set; }
public CauseCode CauseCode { get; set; } public CauseCode CauseCode { get; set; }
public CauseOrigin CauseOrigin { get; set; } public CauseOrigin CauseOrigin { get; set; }
public Protocol Protocol { get; set; } public Protocol Protocol { get; set; }
public Duration Duration { get; set; } public Duration Duration { get; set; }
public CallType CallType { get; set; } public CallType CallType { get; set; }
public CallRate CallRate { get; set; } public CallRate CallRate { get; set; }
public Encryption Encryption { get; set; } public Encryption Encryption { get; set; }
public RequestedURI RequestedURI { get; set; } public RequestedURI RequestedURI { get; set; }
public PeopleCountAverage PeopleCountAverage { get; set; } public PeopleCountAverage PeopleCountAverage { get; set; }
} }
public class UserInterface public class UserInterface
{ {
@ -151,16 +151,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
public string id { get; set; } public string id { get; set; }
public string Value { get; set; } public string Value { get; set; }
} }
public class Event public class Event
{ {
public CallDisconnect CallDisconnect { get; set; } public CallDisconnect CallDisconnect { get; set; }
public UserInterface UserInterface { get; set; } public UserInterface UserInterface { get; set; }
} }
public class RootObject public class RootObject
{ {
public Event Event { get; set; } public Event Event { get; set; }
} }
} }
} }

View file

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

View file

@ -5,6 +5,7 @@ using System.Text;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.Ssh; using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharp;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Core.Intersystem; using PepperDash.Core.Intersystem;
using PepperDash.Core.Intersystem.Tokens; using PepperDash.Core.Intersystem.Tokens;
@ -231,12 +232,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary> /// </summary>
protected void SetIsReady() protected void SetIsReady()
{ {
IsReady = true; CrestronInvoke.BeginInvoke( (o) =>
var h = IsReadyChange; {
if (h != null) try
{ {
h(this, new EventArgs()); IsReady = true;
} var h = IsReadyChange;
if (h != null)
{
h(this, new EventArgs());
}
}
catch (Exception e)
{
Debug.Console(2, this, "Error in SetIsReady() : {0}", e);
}
});
} }
// **** DEBUGGING THINGS **** // **** DEBUGGING THINGS ****

View file

@ -1,3 +1,3 @@
<packages> <packages>
<package id="PepperDashCore" version="1.0.42" targetFramework="net35" allowedVersions="[1.0,1.1)"/> <package id="PepperDashCore" version="1.0.43" targetFramework="net35" allowedVersions="[1.0,1.1)"/>
</packages> </packages>