diff --git a/.gitignore b/.gitignore
index 94b7d400..739a60ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -389,3 +389,4 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
+.DS_Store
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 890b7769..d44e7848 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -91,8 +91,8 @@ we receive and the availability of resources to evaluate contributions, we antic
project remains dynamic and relevant. This may affect our responsiveness and ability to accept pull requests
quickly. This does not mean we are ignoring them.
- Not all innovative ideas need to be accepted as pull requests into this GitHub project to be valuable to the community.
- There may be times when we recommend that you just share your code for some enhancement to Ghidra from your own
- repository. As we identify and recognize extensions that are of general interest to the reverse engineering community, we
+ There may be times when we recommend that you just share your code for some enhancement to Essentials from your own
+ repository. As we identify and recognize extensions that are of general interest to Essentials, we
may seek to incorporate them with our baseline.
## Legal
diff --git a/PepperDashEssentials/Audio/EssentialsVolumeLevelConfig.cs b/PepperDashEssentials/Audio/EssentialsVolumeLevelConfig.cs
index 12108564..d8af5a55 100644
--- a/PepperDashEssentials/Audio/EssentialsVolumeLevelConfig.cs
+++ b/PepperDashEssentials/Audio/EssentialsVolumeLevelConfig.cs
@@ -55,7 +55,7 @@ namespace PepperDash.Essentials
return null;
}
- // DSP format: deviceKey--levelName, biampTesira-1--master
+ // DSP/DMPS format: deviceKey--levelName, biampTesira-1--master
match = Regex.Match(DeviceKey, @"([-_\w]+)--(.+)");
if (match.Success)
{
@@ -67,6 +67,27 @@ namespace PepperDash.Essentials
if (dsp.LevelControlPoints.ContainsKey(levelTag)) // should always...
return dsp.LevelControlPoints[levelTag];
}
+
+ var dmps = DeviceManager.GetDeviceForKey(devKey) as DmpsAudioOutputController;
+ if (dmps != null)
+ {
+ var levelTag = match.Groups[2].Value;
+ switch (levelTag)
+ {
+ case "master":
+ return dmps.MasterVolumeLevel;
+ case "source":
+ return dmps.SourceVolumeLevel;
+ case "micsmaster":
+ return dmps.MicsMasterVolumeLevel;
+ case "codec1":
+ return dmps.Codec1VolumeLevel;
+ case "codec2":
+ return dmps.Codec2VolumeLevel;
+ default:
+ return dmps.MasterVolumeLevel;
+ }
+ }
// No volume for some reason. We have failed as developers
return null;
}
diff --git a/PepperDashEssentials/Bridges/EiscBridge.cs b/PepperDashEssentials/Bridges/EiscBridge.cs
index 21a220ef..c768924b 100644
--- a/PepperDashEssentials/Bridges/EiscBridge.cs
+++ b/PepperDashEssentials/Bridges/EiscBridge.cs
@@ -70,7 +70,7 @@ namespace PepperDash.Essentials.Bridges
catch (NullReferenceException)
{
Debug.ConsoleWithLog(0, this,
- "Please update the bridge config to use EiscBridgeAdvanced with this device: {0}", device.Key);
+ "Please update the bridge config to use eiscApiAdvanced with this device: {0}", device.Key);
}
}
Debug.Console(1, this, "Devices Linked.");
diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs
index dd8f3d5a..1bafbbac 100644
--- a/PepperDashEssentials/ControlSystem.cs
+++ b/PepperDashEssentials/ControlSystem.cs
@@ -13,6 +13,7 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Fusion;
+using PepperDash.Essentials.Core.Web;
using PepperDash.Essentials.Devices.Common;
using PepperDash.Essentials.DM;
using PepperDash.Essentials.Fusion;
@@ -46,28 +47,29 @@ namespace PepperDash.Essentials
///
public override void InitializeSystem()
{
- _startTimer = new CTimer(StartSystem,StartupTime);
-
-
// If the control system is a DMPS type, we need to wait to exit this method until all devices have had time to activate
// to allow any HD-BaseT DM endpoints to register first.
- if (Global.ControlSystemIsDmpsType)
+ bool preventInitializationComplete = Global.ControlSystemIsDmpsType;
+ if (preventInitializationComplete)
{
Debug.Console(1, "******************* InitializeSystem() Entering **********************");
-
- _initializeEvent = new CEvent();
-
+ _startTimer = new CTimer(StartSystem, preventInitializationComplete, StartupTime);
+ _initializeEvent = new CEvent(true, false);
DeviceManager.AllDevicesRegistered += (o, a) =>
{
_initializeEvent.Set();
- Debug.Console(1, "******************* InitializeSystem() Exiting **********************");
};
-
_initializeEvent.Wait(30000);
+ Debug.Console(1, "******************* InitializeSystem() Exiting **********************");
+ SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
+ }
+ else
+ {
+ _startTimer = new CTimer(StartSystem, preventInitializationComplete, StartupTime);
}
}
- private void StartSystem(object obj)
+ private void StartSystem(object preventInitialization)
{
DeterminePlatform();
@@ -79,36 +81,41 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(s =>
- {
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s);
- }, "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(BridgeHelper.JoinmapMarkdown, "getjoinmapmarkdown"
+ , "generate markdown of map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator);
+
+ CrestronConsole.AddNewConsoleCommand(s => Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s), "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
- CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl);
+ CrestronConsole.ConsoleCommandResponse(" {0}{1}", tl, CrestronEnvironment.NewLine);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse
- ("Current running configuration. This is the merged system and template configuration");
+ ("Current running configuration. This is the merged system and template configuration" + CrestronEnvironment.NewLine);
CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject
(ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented));
}, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(s =>
- {
- CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" +
- "System URL: {0}\r\n" +
- "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
- }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.ConsoleCommandResponse(
+ "This system can be found at the following URLs:{2}" +
+ "System URL: {0}{2}" +
+ "Template URL: {1}{2}",
+ ConfigReader.ConfigObject.SystemUrl,
+ ConfigReader.ConfigObject.TemplateUrl,
+ CrestronEnvironment.NewLine),
+ "portalinfo",
+ "Shows portal URLS from configuration",
+ ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(DeviceManager.GetRoutingPorts,
@@ -120,7 +127,10 @@ namespace PepperDash.Essentials
return;
}
- SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
+ if (!(bool)preventInitialization)
+ {
+ SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true;
+ }
}
///
@@ -195,6 +205,8 @@ namespace PepperDash.Essentials
}
else // Handles Linux OS (Virtual Control)
{
+ Debug.SetDebugLevel(2);
+
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", Global.AssemblyVersion);
// Set path to User/
@@ -296,6 +308,10 @@ namespace PepperDash.Essentials
if (!Directory.Exists(pluginDir))
Directory.Create(pluginDir);
+ var joinmapDir = Global.FilePathPrefix + "joinmaps";
+ if(!Directory.Exists(joinmapDir))
+ Directory.Create(joinmapDir);
+
return configExists;
}
@@ -343,6 +359,7 @@ namespace PepperDash.Essentials
// Build the processor wrapper class
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
+ DeviceManager.AddDevice(new EssemtialsWebApi("essentialsWebApi","Essentials Web API"));
// Add global System Monitor device
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
@@ -384,20 +401,21 @@ namespace PepperDash.Essentials
}
else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1)
{
- Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController.");
+ Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController.");
- var butToken = devConf.Properties["buttons"];
- if (butToken != null)
- {
- var buttons = butToken.ToObject>();
- var tpController = new Essentials.Core.Touchpanels.Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons);
- DeviceManager.AddDevice(tpController);
- }
- else
- {
- Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key);
- }
-
+ var butToken = devConf.Properties["buttons"];
+ if (butToken == null)
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Error,
+ "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key);
+ continue;
+ }
+
+ var buttons = butToken.ToObject>();
+ var tpController = new Core.Touchpanels.Mpc3TouchpanelController(
+ string.Format("{0}-keypadButtons", devConf.Key), devConf.Name, Global.ControlSystem, buttons);
+
+ DeviceManager.AddDevice(tpController);
}
else
{
diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj
index e4a0cff6..66a20f72 100644
--- a/PepperDashEssentials/PepperDashEssentials.csproj
+++ b/PepperDashEssentials/PepperDashEssentials.csproj
@@ -71,7 +71,7 @@
..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll
-
+
False
..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll
diff --git a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs
index 50186d0b..cbe1b579 100644
--- a/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs
+++ b/PepperDashEssentials/Room/Types/EssentialsCombinedHuddleVtc1Room.cs
@@ -226,66 +226,66 @@ namespace PepperDash.Essentials
}
}
- void Initialize()
+ public override void Initialize()
{
try
{
- if (DefaultAudioDevice is IBasicVolumeControls)
- DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
- else if (DefaultAudioDevice is IHasVolumeDevice)
- DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
- CurrentVolumeControls = DefaultVolumeControls;
+ //if (DefaultAudioDevice is IBasicVolumeControls)
+ // DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
+ //else if (DefaultAudioDevice is IHasVolumeDevice)
+ // DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
+ //CurrentVolumeControls = DefaultVolumeControls;
- // Combines call feedback from both codecs if available
- InCallFeedback = new BoolFeedback(() =>
- {
- bool inAudioCall = false;
- bool inVideoCall = false;
+ //// Combines call feedback from both codecs if available
+ //InCallFeedback = new BoolFeedback(() =>
+ //{
+ // bool inAudioCall = false;
+ // bool inVideoCall = false;
- if (AudioCodec != null)
- inAudioCall = AudioCodec.IsInCall;
+ // if (AudioCodec != null)
+ // inAudioCall = AudioCodec.IsInCall;
- if (VideoCodec != null)
- inVideoCall = VideoCodec.IsInCall;
+ // if (VideoCodec != null)
+ // inVideoCall = VideoCodec.IsInCall;
- if (inAudioCall || inVideoCall)
- return true;
- else
- return false;
- });
+ // if (inAudioCall || inVideoCall)
+ // return true;
+ // else
+ // return false;
+ //});
- SetupDisplays();
+ //SetupDisplays();
- // Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
- this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
+ //// Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
+ //this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
- Debug.Console(2, this, "Microphone Privacy Config evaluated.");
+ //Debug.Console(2, this, "Microphone Privacy Config evaluated.");
- // Get emergency object, if any
- this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
+ //// Get emergency object, if any
+ //this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
- Debug.Console(2, this, "Emergency Config evaluated.");
+ //Debug.Console(2, this, "Emergency Config evaluated.");
- VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
- VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
+ //VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
+ //VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
- if (AudioCodec != null)
- AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
+ //if (AudioCodec != null)
+ // AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
- IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
- VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
+ //IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
+ //VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
- // link privacy to VC (for now?)
- PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
- VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
+ //// link privacy to VC (for now?)
+ //PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
+ //VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
- CallTypeFeedback = new IntFeedback(() => 0);
+ //CallTypeFeedback = new IntFeedback(() => 0);
SetSourceListKey();
- EnablePowerOnToLastSource = true;
+ //EnablePowerOnToLastSource = true;
}
catch (Exception e)
{
@@ -297,7 +297,9 @@ namespace PepperDash.Essentials
{
//DefaultDisplay = DeviceManager.GetDeviceForKey(PropertiesConfig.DefaultDisplayKey) as IRoutingSinkWithSwitching;
- var destinationList = ConfigReader.ConfigObject.DestinationLists[PropertiesConfig.DestinationListKey];
+ var destinationList = ConfigReader.ConfigObject.DestinationLists[PropertiesConfig.DestinationListKey];
+
+ Displays.Clear();
foreach (var destination in destinationList)
{
@@ -314,37 +316,54 @@ namespace PepperDash.Essentials
// Link power, warming, cooling to display
var dispTwoWay = display as IHasPowerControlWithFeedback;
if (dispTwoWay != null)
- {
- dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
- {
- if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
- {
- //if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
- // CurrentSourceInfo = null;
- OnFeedback.FireUpdate();
- }
- if (dispTwoWay.PowerIsOnFeedback.BoolValue)
- {
- SetDefaultLevels();
- }
- };
- }
-
- display.IsWarmingUpFeedback.OutputChange += (o, a) =>
- {
- IsWarmingUpFeedback.FireUpdate();
- if (!IsWarmingUpFeedback.BoolValue)
- (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
- };
- display.IsCoolingDownFeedback.OutputChange += (o, a) =>
- {
- IsCoolingDownFeedback.FireUpdate();
- };
+ {
+ dispTwoWay.PowerIsOnFeedback.OutputChange -= PowerIsOnFeedback_OutputChange;
+ dispTwoWay.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
+
+ if (dispTwoWay.PowerIsOnFeedback.BoolValue)
+ {
+ SetDefaultLevels();
+ }
+ }
+
+ display.IsWarmingUpFeedback.OutputChange -= IsWarmingUpFeedback_OutputChange;
+ display.IsWarmingUpFeedback.OutputChange += IsWarmingUpFeedback_OutputChange;
+
+ display.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
+ display.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
}
}
+ }
+
+ void IsCoolingDownFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ IsCoolingDownFeedback.FireUpdate();
+ }
+
+ void IsWarmingUpFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ IsWarmingUpFeedback.FireUpdate();
+ if (!IsWarmingUpFeedback.BoolValue)
+ (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
+ }
+
+ void PowerIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ var dispTwoWay = sender as IHasPowerControlWithFeedback;
+
+ if (dispTwoWay != null && dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
+ {
+ //if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
+ // CurrentSourceInfo = null;
+ OnFeedback.FireUpdate();
+ }
}
+
+
+
+
private void SetSourceListKey()
{
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
@@ -354,9 +373,9 @@ namespace PepperDash.Essentials
else
{
SetSourceListKey(Key);
- }
-
- SetCodecExternalSources();
+ }
+
+ SetUpVideoCodec();
}
protected override void CustomSetConfig(DeviceConfig config)
@@ -367,26 +386,150 @@ namespace PepperDash.Essentials
PropertiesConfig = newPropertiesConfig;
ConfigWriter.UpdateRoomConfig(config);
+ }
+
+ public override bool Deactivate()
+ {
+ // Stop listining to this event when room deactivated
+ VideoCodec.IsReadyChange -= VideoCodec_IsReadyChange;
+
+ // Clear occupancy
+ RoomOccupancy = null;
+
+ Debug.Console(0, this, "Room '{0}' Deactivated", Name);
+
+ return base.Deactivate();
}
public override bool CustomActivate()
- {
- // Add Occupancy object from config
- if (PropertiesConfig.Occupancy != null)
- {
- Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
- this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
- IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
- }
-
- this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
- this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
-
- this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
- this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
-
+ {
+ try
+ {
+ if (DefaultAudioDevice is IBasicVolumeControls)
+ DefaultVolumeControls = DefaultAudioDevice as IBasicVolumeControls;
+ else if (DefaultAudioDevice is IHasVolumeDevice)
+ DefaultVolumeControls = (DefaultAudioDevice as IHasVolumeDevice).VolumeDevice;
+ CurrentVolumeControls = DefaultVolumeControls;
+
+
+ // Combines call feedback from both codecs if available
+ InCallFeedback = new BoolFeedback(() =>
+ {
+ bool inAudioCall = false;
+ bool inVideoCall = false;
+
+ if (AudioCodec != null)
+ inAudioCall = AudioCodec.IsInCall;
+
+ if (VideoCodec != null)
+ inVideoCall = VideoCodec.IsInCall;
+
+ if (inAudioCall || inVideoCall)
+ return true;
+ else
+ return false;
+ });
+
+ SetupDisplays();
+
+ // Get Microphone Privacy object, if any MUST HAPPEN AFTER setting InCallFeedback
+ this.MicrophonePrivacy = EssentialsRoomConfigHelper.GetMicrophonePrivacy(PropertiesConfig, this);
+
+ Debug.Console(2, this, "Microphone Privacy Config evaluated.");
+
+ // Get emergency object, if any
+ this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
+
+ Debug.Console(2, this, "Emergency Config evaluated.");
+
+ if (AudioCodec != null)
+ {
+ AudioCodec.CallStatusChange -= AudioCodec_CallStatusChange;
+ AudioCodec.CallStatusChange += AudioCodec_CallStatusChange;
+ }
+
+ VideoCodec.CallStatusChange -= VideoCodec_CallStatusChange;
+ VideoCodec.CallStatusChange += VideoCodec_CallStatusChange;
+
+ VideoCodec.IsReadyChange -= VideoCodec_IsReadyChange;
+ VideoCodec.IsReadyChange += VideoCodec_IsReadyChange;
+
+ VideoCodec.SharingContentIsOnFeedback.OutputChange -= SharingContentIsOnFeedback_OutputChange;
+ VideoCodec.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
+
+
+ IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
+
+ // link privacy to VC (for now?)
+ PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
+
+ VideoCodec.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
+ VideoCodec.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
+
+ CallTypeFeedback = new IntFeedback(() => 0);
+
+ SetSourceListKey();
+
+ EnablePowerOnToLastSource = true;
+
+
+ // Add Occupancy object from config
+ if (PropertiesConfig.Occupancy != null)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
+ this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
+ IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
+ }
+
+ this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
+ this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
+
+ this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
+ this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
+
+ }
+ catch (Exception e)
+ {
+ Debug.Console(0, this, "Error Activiating Room: {0}", e);
+ }
+
+
+ Debug.Console(0, this, "Room '{0}' Activated", Name);
return base.CustomActivate();
- }
+ }
+
+ void AudioCodec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ InCallFeedback.FireUpdate();
+ }
+
+ void PrivacyModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ PrivacyModeIsOnFeedback.FireUpdate();
+ }
+
+ void VideoCodec_IsReadyChange(object sender, EventArgs e)
+ {
+ SetUpVideoCodec();
+ }
+
+ void SetUpVideoCodec()
+ {
+ SetCodecExternalSources();
+ SetCodecBranding();
+ }
+
+ void VideoCodec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ InCallFeedback.FireUpdate();
+ }
+
+ void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ IsSharingFeedback.FireUpdate();
+ }
+
+
///
///
@@ -779,7 +922,9 @@ namespace PepperDash.Essentials
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);
}
- }
+ }
+
+ Debug.Console(1, this, "Successfully set up codec external sources for room: {0}", Name);
}
catch (Exception e)
{
diff --git a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
index e622983f..2aae2f75 100644
--- a/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
+++ b/PepperDashEssentials/Room/Types/EssentialsHuddleVtc1Room.cs
@@ -19,6 +19,8 @@ namespace PepperDash.Essentials
{
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IEssentialsHuddleVtc1Room
{
+ private IEssentialsRoomCombiner _roomCombiner;
+
private bool _codecExternalSourceChange;
public event EventHandler CurrentVolumeDeviceChange;
public event SourceInfoChangeHandler CurrentSourceChange;
@@ -234,7 +236,7 @@ namespace PepperDash.Essentials
throw new ArgumentNullException("DefaultAudioDevice cannot be null");
}
- InitializeRoom();
+ Initialize();
}
catch (Exception e)
{
@@ -242,8 +244,65 @@ namespace PepperDash.Essentials
}
}
- void InitializeRoom()
- {
+
+ private void SetupEnvironmentalControlDevices()
+ {
+ if (PropertiesConfig.Environment != null)
+ {
+ if (PropertiesConfig.Environment.Enabled)
+ {
+ EnvironmentalControlDevices.Clear();
+
+ foreach (var d in PropertiesConfig.Environment.DeviceKeys)
+ {
+ var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
+ EnvironmentalControlDevices.Add(envDevice);
+ }
+ }
+ }
+ }
+
+
+ private void SetSourceListKey()
+ {
+ if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
+ {
+ SetSourceListKey(PropertiesConfig.SourceListKey);
+ }
+ else
+ {
+ SetSourceListKey(Key);
+ }
+
+ SetUpVideoCodec();
+ }
+
+ protected override void CustomSetConfig(DeviceConfig config)
+ {
+ var newPropertiesConfig = JsonConvert.DeserializeObject(config.Properties.ToString());
+
+ if (newPropertiesConfig != null)
+ PropertiesConfig = newPropertiesConfig;
+
+ ConfigWriter.UpdateRoomConfig(config);
+ }
+
+ public override bool Deactivate()
+ {
+
+ // Stop listining to this event when room deactivated
+ VideoCodec.IsReadyChange -= VideoCodec_IsReadyChange;
+
+ // Clear occupancy
+ RoomOccupancy = null;
+
+ Debug.Console(0, this, "Room '{0}' Deactivated", Name);
+
+ return base.Deactivate();
+ }
+
+ public override bool CustomActivate()
+ {
try
{
if (DefaultAudioDevice is IBasicVolumeControls)
@@ -278,32 +337,15 @@ namespace PepperDash.Essentials
var dispTwoWay = disp as IHasPowerControlWithFeedback;
if (dispTwoWay != null)
{
- dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
- {
- if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
- {
- if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
- CurrentSourceInfo = null;
- OnFeedback.FireUpdate();
- }
- if (dispTwoWay.PowerIsOnFeedback.BoolValue)
- {
- SetDefaultLevels();
- }
- };
+ dispTwoWay.PowerIsOnFeedback.OutputChange -= PowerIsOnFeedback_OutputChange;
+ dispTwoWay.PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
}
- disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
- {
- IsWarmingUpFeedback.FireUpdate();
- if (!IsWarmingUpFeedback.BoolValue)
- (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
- };
- disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
- {
- IsCoolingDownFeedback.FireUpdate();
- };
+ disp.IsWarmingUpFeedback.OutputChange -= IsWarmingUpFeedback_OutputChange;
+ disp.IsWarmingUpFeedback.OutputChange += IsWarmingUpFeedback_OutputChange;
+ disp.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
+ disp.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
}
@@ -317,20 +359,30 @@ namespace PepperDash.Essentials
this.Emergency = EssentialsRoomConfigHelper.GetEmergency(PropertiesConfig, this);
Debug.Console(2, this, "Emergency Config evaluated.");
-
-
- VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
- VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
-
+
if (AudioCodec != null)
- AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
+ {
+ AudioCodec.CallStatusChange -= AudioCodec_CallStatusChange;
+ AudioCodec.CallStatusChange += AudioCodec_CallStatusChange;
+ }
+
+ VideoCodec.CallStatusChange -= VideoCodec_CallStatusChange;
+ VideoCodec.CallStatusChange += VideoCodec_CallStatusChange;
+
+ VideoCodec.IsReadyChange -= VideoCodec_IsReadyChange;
+ VideoCodec.IsReadyChange += VideoCodec_IsReadyChange;
+
+ VideoCodec.SharingContentIsOnFeedback.OutputChange -= SharingContentIsOnFeedback_OutputChange;
+ VideoCodec.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange;
+
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingContentIsOnFeedback.BoolValue);
- VideoCodec.SharingContentIsOnFeedback.OutputChange += (o, a) => this.IsSharingFeedback.FireUpdate();
// link privacy to VC (for now?)
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
- VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
+
+ VideoCodec.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
+ VideoCodec.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
CallTypeFeedback = new IntFeedback(() => 0);
@@ -339,72 +391,92 @@ namespace PepperDash.Essentials
SetSourceListKey();
EnablePowerOnToLastSource = true;
+
+
+ // Add Occupancy object from config
+ if (PropertiesConfig.Occupancy != null)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
+ this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
+ IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
+ }
+
+ this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
+ this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
+
+ this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
+ this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
}
catch (Exception e)
{
- Debug.Console(0, this, "Error Initializing Room: {0}", e);
- }
- }
-
- private void SetupEnvironmentalControlDevices()
- {
- if (PropertiesConfig.Environment != null)
- {
- if (PropertiesConfig.Environment.Enabled)
- {
- foreach (var d in PropertiesConfig.Environment.DeviceKeys)
- {
- var envDevice = DeviceManager.GetDeviceForKey(d) as EssentialsDevice;
- EnvironmentalControlDevices.Add(envDevice);
- }
- }
- }
- }
-
-
- private void SetSourceListKey()
- {
- if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
- {
- SetSourceListKey(PropertiesConfig.SourceListKey);
- }
- else
- {
- SetSourceListKey(Key);
+ Debug.Console(0, this, "Error Activiating Room: {0}", e);
}
- SetCodecExternalSources();
- }
-
- protected override void CustomSetConfig(DeviceConfig config)
- {
- var newPropertiesConfig = JsonConvert.DeserializeObject(config.Properties.ToString());
-
- if (newPropertiesConfig != null)
- PropertiesConfig = newPropertiesConfig;
-
- ConfigWriter.UpdateRoomConfig(config);
- }
-
- public override bool CustomActivate()
- {
- // Add Occupancy object from config
- if (PropertiesConfig.Occupancy != null)
- {
- Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Setting Occupancy Provider for room");
- this.SetRoomOccupancy(DeviceManager.GetDeviceForKey(PropertiesConfig.Occupancy.DeviceKey) as
- IOccupancyStatusProvider, PropertiesConfig.Occupancy.TimeoutMinutes);
- }
-
- this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
- this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
-
- this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
- this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
-
+ Debug.Console(0, this, "Room '{0}' Activated", Name);
return base.CustomActivate();
}
+ void PrivacyModeIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ PrivacyModeIsOnFeedback.FireUpdate();
+ }
+
+ void SharingContentIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ IsSharingFeedback.FireUpdate();
+ }
+
+ void AudioCodec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ InCallFeedback.FireUpdate();
+ }
+
+ void VideoCodec_IsReadyChange(object sender, EventArgs e)
+ {
+ SetUpVideoCodec();
+ }
+
+ void SetUpVideoCodec()
+ {
+ SetCodecExternalSources();
+ SetCodecBranding();
+ }
+
+ void VideoCodec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
+ {
+ InCallFeedback.FireUpdate();
+ }
+
+ void IsCoolingDownFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ IsCoolingDownFeedback.FireUpdate();
+ }
+
+ void IsWarmingUpFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ IsWarmingUpFeedback.FireUpdate();
+ if (!IsWarmingUpFeedback.BoolValue)
+ (CurrentVolumeControls as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
+
+ }
+
+ void PowerIsOnFeedback_OutputChange(object sender, FeedbackEventArgs e)
+ {
+ var dispTwoWay = DefaultDisplay as IHasPowerControlWithFeedback;
+
+ if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
+ {
+ if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
+ CurrentSourceInfo = null;
+ OnFeedback.FireUpdate();
+ }
+ if (dispTwoWay.PowerIsOnFeedback.BoolValue)
+ {
+ SetDefaultLevels();
+ }
+
+ }
+
///
@@ -745,6 +817,28 @@ namespace PepperDash.Essentials
{
//Implement this
}
+
+ protected override bool AllowVacancyTimerToStart()
+ {
+ bool allowVideo = true;
+ bool allowAudio = true;
+
+ if (VideoCodec != null)
+ {
+ Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in a video call", Key, VideoCodec.IsInCall ? "is" : "is not");
+ allowVideo = !VideoCodec.IsInCall;
+ }
+
+ if (AudioCodec != null)
+ {
+ Debug.Console(2,this, Debug.ErrorLogLevel.Notice, "Room {0} {1} in an audio call", Key, AudioCodec.IsInCall ? "is" : "is not");
+ allowAudio = !AudioCodec.IsInCall;
+ }
+
+ Debug.Console(2, this, "Room {0} allowing vacancy timer to start: {1}", Key, allowVideo && allowAudio);
+
+ return allowVideo && allowAudio;
+ }
///
/// Does what it says
@@ -810,6 +904,8 @@ namespace PepperDash.Essentials
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
}
}
+ Debug.Console(1, this, "Successfully set up codec external sources for room: {0}", Name);
+
}
catch (Exception e)
{
diff --git a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
index b97ef9c4..65cc52fa 100644
--- a/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
+++ b/PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
@@ -272,7 +272,7 @@ namespace PepperDash.Essentials
{
Debug.Console(2, this,
@"Attempting to run action:
-DeviceKey: {0}
+Key: {0}
MethodName: {1}
Params: {2}"
, a.DeviceKey, a.MethodName, a.Params);
diff --git a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs
deleted file mode 100644
index 45074fb7..00000000
--- a/PepperDashEssentials/Room/Types/IEssentialsHuddleSpaceRoom.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.DeviceTypeInterfaces;
-using PepperDash.Essentials.Room.Config;
-using PepperDash.Essentials.Core.Devices;
-using PepperDash.Essentials.Devices.Common.Codec;
-using PepperDash.Essentials.Devices.Common.VideoCodec;
-using PepperDash.Essentials.Devices.Common.AudioCodec;
-
-
-using PepperDash.Core;
-
-namespace PepperDash.Essentials
-{
- public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IHasDefaultDisplay
- {
- bool ExcludeFromGlobalFunctions { get; }
-
- void RunRouteAction(string routeKey);
-
- EssentialsHuddleRoomPropertiesConfig PropertiesConfig { get; }
-
- IBasicVolumeControls CurrentVolumeControls { get; }
-
- event EventHandler CurrentVolumeDeviceChange;
- }
-
- public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
- IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay
- {
- EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
-
- void RunRouteAction(string routeKey);
-
- IHasScheduleAwareness ScheduleSource { get; }
-
- string DefaultCodecRouteString { get; }
- }
-}
\ No newline at end of file
diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs
index 41616d96..dccae06a 100644
--- a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs
+++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleSpaceRoom.cs
@@ -7,7 +7,8 @@ using PepperDash.Essentials.Room.Config;
namespace PepperDash.Essentials
{
- public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay, IHasCurrentVolumeControls
+ public interface IEssentialsHuddleSpaceRoom : IEssentialsRoom, IHasCurrentSourceInfoChange, IRunRouteAction, IRunDefaultPresentRoute, IHasDefaultDisplay, IHasCurrentVolumeControls, IRoomOccupancy,
+ IEmergency, IMicrophonePrivacy
{
bool ExcludeFromGlobalFunctions { get; }
diff --git a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs
index 03f7340b..85937828 100644
--- a/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs
+++ b/PepperDashEssentials/Room/Types/Interfaces/IEssentialsHuddleVtc1Room.cs
@@ -8,7 +8,8 @@ using PepperDash.Essentials.Devices.Common.AudioCodec;
namespace PepperDash.Essentials
{
public interface IEssentialsHuddleVtc1Room : IEssentialsRoom, IHasCurrentSourceInfoChange,
- IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
+ IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback,
+ IRoomOccupancy, IEmergency, IMicrophonePrivacy
{
EssentialsHuddleVtc1PropertiesConfig PropertiesConfig { get; }
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs
index a1326770..5073d957 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/BridgeBase.cs
@@ -46,6 +46,33 @@ namespace PepperDash.Essentials.Core.Bridges
bridge.PrintJoinMaps();
}
}
+ public static void JoinmapMarkdown(string command)
+ {
+ var targets = command.Split(' ');
+
+ var bridgeKey = targets[0].Trim();
+
+ var bridge = DeviceManager.GetDeviceForKey(bridgeKey) as EiscApiAdvanced;
+
+ if (bridge == null)
+ {
+ Debug.Console(0, "Unable to find advanced bridge with key: '{0}'", bridgeKey);
+ return;
+ }
+
+ if (targets.Length > 1)
+ {
+ var deviceKey = targets[1].Trim();
+
+ if (string.IsNullOrEmpty(deviceKey)) return;
+ bridge.MarkdownJoinMapForDevice(deviceKey, bridgeKey);
+ }
+ else
+ {
+ bridge.MarkdownForBridge(bridgeKey);
+
+ }
+ }
}
@@ -82,7 +109,7 @@ namespace PepperDash.Essentials.Core.Bridges
{
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
- protected Dictionary JoinMaps { get; private set; }
+ public Dictionary JoinMaps { get; private set; }
public BasicTriList Eisc { get; private set; }
@@ -138,7 +165,7 @@ namespace PepperDash.Essentials.Core.Bridges
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
- if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
+ if (!typeof(IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
{
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
@@ -227,6 +254,19 @@ namespace PepperDash.Essentials.Core.Bridges
joinMap.Value.PrintJoinMapInfo();
}
}
+ ///
+ /// Generates markdown for all join maps on this bridge
+ ///
+ public virtual void MarkdownForBridge(string bridgeKey)
+ {
+ Debug.Console(0, this, "Writing Joinmaps to files for EISC IPID: {0}", Eisc.ID.ToString("X"));
+
+ foreach (var joinMap in JoinMaps)
+ {
+ Debug.Console(0, "Generating markdown for device '{0}':", joinMap.Key);
+ joinMap.Value.MarkdownJoinMapInfo(joinMap.Key, bridgeKey);
+ }
+ }
///
/// Prints the join map for a device by key
@@ -242,9 +282,26 @@ namespace PepperDash.Essentials.Core.Bridges
return;
}
- Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
+ Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
joinMap.PrintJoinMapInfo();
}
+ ///
+ /// Prints the join map for a device by key
+ ///
+ ///
+ public void MarkdownJoinMapForDevice(string deviceKey, string bridgeKey)
+ {
+ var joinMap = JoinMaps[deviceKey];
+
+ if (joinMap == null)
+ {
+ Debug.Console(0, this, "Unable to find joinMap for device with key: '{0}'", deviceKey);
+ return;
+ }
+
+ Debug.Console(0, "Join map for device '{0}' on EISC '{1}':", deviceKey, Key);
+ joinMap.MarkdownJoinMapInfo(deviceKey, bridgeKey);
+ }
///
/// Used for debugging to trigger an action based on a join number and type
@@ -352,7 +409,7 @@ namespace PepperDash.Essentials.Core.Bridges
public List Devices { get; set; }
[JsonProperty("rooms")]
- public List Rooms { get; set; }
+ public List Rooms { get; set; }
public class ApiDevicePropertiesConfig
@@ -385,7 +442,7 @@ namespace PepperDash.Essentials.Core.Bridges
{
public EiscApiAdvancedFactory()
{
- TypeNames = new List { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
+ TypeNames = new List { "eiscapiadv", "eiscapiadvanced", "eiscapiadvancedserver", "eiscapiadvancedclient", "vceiscapiadv", "vceiscapiadvanced" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -394,35 +451,51 @@ namespace PepperDash.Essentials.Core.Bridges
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
+ BasicTriList eisc;
+
switch (dc.Type.ToLower())
{
case "eiscapiadv":
case "eiscapiadvanced":
- {
- var eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
- controlProperties.TcpSshProperties.Address, Global.ControlSystem);
- return new EiscApiAdvanced(dc, eisc);
- }
+ {
+ eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
+ controlProperties.TcpSshProperties.Address, Global.ControlSystem);
+ break;
+ }
case "eiscapiadvancedserver":
- {
- var eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
- return new EiscApiAdvanced(dc, eisc);
- }
+ {
+ eisc = new EISCServer(controlProperties.IpIdInt, Global.ControlSystem);
+ break;
+ }
case "eiscapiadvancedclient":
- {
- var eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
- return new EiscApiAdvanced(dc, eisc);
- }
+ {
+ eisc = new EISCClient(controlProperties.IpIdInt, controlProperties.TcpSshProperties.Address, Global.ControlSystem);
+ break;
+ }
case "vceiscapiadv":
case "vceiscapiadvanced":
- {
- var eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, InitialParametersClass.RoomId,
- Global.ControlSystem);
- return new EiscApiAdvanced(dc, eisc);
- }
+ {
+ if (string.IsNullOrEmpty(controlProperties.RoomId))
+ {
+ Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to build VC-4 EISC Client for device {0}. Room ID is missing or empty", dc.Key);
+ eisc = null;
+ break;
+ }
+ eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, controlProperties.RoomId,
+ Global.ControlSystem);
+ break;
+ }
default:
- return null;
+ eisc = null;
+ break;
}
+
+ if (eisc == null)
+ {
+ return null;
+ }
+
+ return new EiscApiAdvanced(dc, eisc);
}
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs
index 126c6112..170da721 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/AirMediaControllerJoinMap.cs
@@ -20,6 +20,18 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete AutomaticInputRoutingEnabled = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "Air Media Automatic Input Routing Enable(d)", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+ [JoinName("HdmiInHdcpSupportOn")]
+ public JoinDataComplete HdmiInHdcpSupportOn = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
+ new JoinMetadata { Description = "Turns on HDCP support for HDMI in. Reports state as FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("HdmiInHdcpSupportOff")]
+ public JoinDataComplete HdmiInHdcpSupportOff = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
+ new JoinMetadata { Description = "Turns off HDCP support for HDMI in. Reports state as FB", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("HdmiInDisabledByHdcp")]
+ public JoinDataComplete HdmiInDisabledByHdcp = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
+ new JoinMetadata { Description = "Reports if ", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
[JoinName("VideoOut")]
public JoinDataComplete VideoOut = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Air Media Video Route Select / Feedback", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs
index ec4661a4..8352bb1d 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmRmcControllerJoinMap.cs
@@ -8,6 +8,18 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete IsOnline = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC Online", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+ [JoinName("VideoMuteOn")]
+ public JoinDataComplete VideoMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM RMC Mute Video", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("VideoMuteOff")]
+ public JoinDataComplete VideoMuteOff = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM RMC UnMute Video", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("VideoMuteToggle")]
+ public JoinDataComplete VideoMuteToggle = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM RMC Mute Video Toggle", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
+
[JoinName("CurrentOutputResolution")]
public JoinDataComplete CurrentOutputResolution = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC Current Output Resolution", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
@@ -36,6 +48,34 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete AudioVideoSource = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM RMC Audio Video Source Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+ [JoinName("HdcpSupportCapability")]
+ public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM RMC HDCP Support Capability", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("Port1HdcpState")]
+ public JoinDataComplete Port1HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM RMC Port 1 (DM) HDCP State Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("Port2HdcpState")]
+ public JoinDataComplete Port2HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM TX Port 2 (HDMI) HDCP State Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("HdmiInputSync")]
+ public JoinDataComplete HdmiInputSync = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM RMC HDMI Input Sync", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("HdcpInputPortCount")]
+ public JoinDataComplete HdcpInputPortCount = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
+ new JoinMetadata { Description = "Number of Input Ports that support HDCP", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("ScalerOutWallMode")]
+ public JoinDataComplete ScalerOutWallMode = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
+ new JoinMetadata { Description = "Set Wall Mode for Scaler video Wall mode", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("ScalerOutWallModeRaw")]
+ public JoinDataComplete ScalerOutWallModeRaw = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 },
+ new JoinMetadata { Description = "Set Wall Mode for Scaler video Wall mode", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+
///
/// Constructor to use when instantiating this Join Map without inheriting from it
///
@@ -50,7 +90,8 @@ namespace PepperDash.Essentials.Core.Bridges
///
/// Join this join map will start at
/// Type of the child join map
- protected DmRmcControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
+ protected DmRmcControllerJoinMap(uint joinStart, Type type)
+ : base(joinStart, type)
{
}
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs
index 6d783639..d75d0dad 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/DmTxControllerJoinMap.cs
@@ -64,6 +64,16 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete VgaContrast = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 },
new JoinMetadata { Description = "DM TX Online", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+ [JoinName("Port3HdcpState")]
+ public JoinDataComplete Port3HdcpState = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
+ new JoinMetadata { Description = "DM TX Port 3 HDCP State Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+
+ [JoinName("HdcpInputPortCount")]
+ public JoinDataComplete HdcpInputPortCount = new JoinDataComplete(new JoinData { JoinNumber = 9, JoinSpan = 1 },
+ new JoinMetadata { Description = "Number of Input Ports that support HDCP", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
+
+
+
///
/// Constructor to use when instantiating this Join Map without inheriting from it
///
@@ -78,7 +88,8 @@ namespace PepperDash.Essentials.Core.Bridges
///
/// Join this join map will start at
/// Type of the child join map
- protected DmTxControllerJoinMap(uint joinStart, Type type) : base(joinStart, type)
+ protected DmTxControllerJoinMap(uint joinStart, Type type)
+ : base(joinStart, type)
{
}
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericIrControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericIrControllerJoinMap.cs
new file mode 100644
index 00000000..288141bb
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/GenericIrControllerJoinMap.cs
@@ -0,0 +1,827 @@
+using PepperDash.Essentials.Core;
+
+namespace PepperDash_Essentials_Core.Bridges.JoinMaps
+{
+ public sealed class GenericIrControllerJoinMap : JoinMapBaseAdvanced
+ {
+ [JoinName("PLAY")]
+ public JoinDataComplete Play = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 1,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "PLAY",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("STOP")]
+ public JoinDataComplete Stop = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 2,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "STOP",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("PAUSE")]
+ public JoinDataComplete Pause = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 3,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "PAUSE",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("FSCAN")]
+ public JoinDataComplete ForwardScan = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 4,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "FSCAN",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("RSCAN")]
+ public JoinDataComplete ReverseScan = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 5,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "RSCAN",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("F_SKIP")]
+ public JoinDataComplete ForwardSkip = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 6,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "F_SKIP",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("R_SKIP")]
+ public JoinDataComplete ReverseSkip = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 7,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "R_SKIP",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("RECORD")]
+ public JoinDataComplete Record = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 8,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "RECORD",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("POWER")]
+ public JoinDataComplete Power = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 9,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "POWER",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("0")]
+ public JoinDataComplete Kp0 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 10,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "0",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("1")]
+ public JoinDataComplete Kp1 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 11,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "1",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("2")]
+ public JoinDataComplete Kp2 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 12,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "2",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("3")]
+ public JoinDataComplete Kp3 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 13,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "3",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("4")]
+ public JoinDataComplete Kp4 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 14,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "4",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("5")]
+ public JoinDataComplete Kp5 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 15,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "5",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("6")]
+ public JoinDataComplete Kp6 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 16,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "6",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("7")]
+ public JoinDataComplete Kp7 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 17,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "7",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("8")]
+ public JoinDataComplete Kp8 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 18,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "8",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("9")]
+ public JoinDataComplete Kp9 = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 19,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "9",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ // [JoinName("+10")]
+ // public JoinDataComplete Kp9 = new JoinDataComplete(
+ // new JoinData
+ // {
+ // JoinNumber = 20,
+ // JoinSpan = 1
+ // },
+ // new JoinMetadata
+ // {
+ // Description = "+10",
+ // JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ // JoinType = eJoinType.Digital
+ // });
+
+ [JoinName("ENTER")]
+ public JoinDataComplete Enter = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 21,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "ENTER",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("CH+")]
+ public JoinDataComplete ChannelUp = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 22,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "CH+",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("CH-")]
+ public JoinDataComplete ChannelDown = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 23,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "CH-",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("*")]
+ public JoinDataComplete KpStar = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 24,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "*",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("#")]
+ public JoinDataComplete KpPound = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 25,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "#",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ // [JoinName(".")]
+ // public JoinDataComplete KpPound = new JoinDataComplete(
+ // new JoinData
+ // {
+ // JoinNumber = 26,
+ // JoinSpan = 1
+ // },
+ // new JoinMetadata
+ // {
+ // Description = ".",
+ // JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ // JoinType = eJoinType.Digital
+ // });
+
+ [JoinName("POWER_ON")]
+ public JoinDataComplete PowerOn = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 27,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "POWER_ON",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("POWER_OFF")]
+ public JoinDataComplete PowerOff = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 28,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "POWER_OFF",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("PLAY_PAUSE")]
+ public JoinDataComplete PlayPause = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 29,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "PLAY_PAUSE",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("LAST")]
+ public JoinDataComplete Last = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 30,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "LAST",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("HOME")]
+ public JoinDataComplete Home = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 40,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "HOME",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("BACK")]
+ public JoinDataComplete Back = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 41,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "BACK",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("GUIDE")]
+ public JoinDataComplete Guide = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 42,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "GUIDE",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("INFO")]
+ public JoinDataComplete Info = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 43,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "INFO",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("MENU")]
+ public JoinDataComplete Menu = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 44,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "MENU",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("UP_ARROW")]
+ public JoinDataComplete DpadUp = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 45,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "UP_ARROW",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("DN_ARROW")]
+ public JoinDataComplete DpadDown = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 46,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "DN_ARROW",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("LEFT_ARROW")]
+ public JoinDataComplete DpadLeft = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 47,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "LEFT_ARROW",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("RIGHT_ARROW")]
+ public JoinDataComplete DpadRight = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 48,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "RIGHT_ARROW",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("SELECT")]
+ public JoinDataComplete DpadSelect = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 49,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "SELECT",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("OPTIONS")]
+ public JoinDataComplete Options = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 50,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "OPTIONS",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("RETURN")]
+ public JoinDataComplete Return = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 51,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "RETURN",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("DVR")]
+ public JoinDataComplete Dvr = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 52,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "DVR",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("ON_DEMAND")]
+ public JoinDataComplete OnDemand = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 53,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "ON_DEMAND",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("PAGE_UP")]
+ public JoinDataComplete PageUp = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 54,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "PAGE_UP",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("PAGE_DOWN")]
+ public JoinDataComplete PageDown = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 55,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "PAGE_DOWN",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("F_SRCH")]
+ public JoinDataComplete ForwardSearch = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 56,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "F_SRCH",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("R_SRCH")]
+ public JoinDataComplete ReverseSearch = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 57,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "R_SRCH",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("TRACK+")]
+ public JoinDataComplete TrackPlus = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 58,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "TRACK+",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("TRACK-")]
+ public JoinDataComplete TrackMinus = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 59,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "TRACK-",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("A")]
+ public JoinDataComplete KpA = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 61,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "A",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("B")]
+ public JoinDataComplete KpB = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 62,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "B",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("C")]
+ public JoinDataComplete KpC = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 63,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "C",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("D")]
+ public JoinDataComplete KpD = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 64,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "D",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("RED")]
+ public JoinDataComplete KpRed = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 65,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "RED",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("GREEN")]
+ public JoinDataComplete KpGreen = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 66,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "GREEN",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("YELLOW")]
+ public JoinDataComplete KpYellow = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 67,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "YELLOW",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ [JoinName("BLUE")]
+ public JoinDataComplete KpBlue = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 68,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "BLUE",
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ public GenericIrControllerJoinMap(uint joinStart)
+ : base(joinStart, typeof(GenericIrControllerJoinMap))
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs
new file mode 100644
index 00000000..3f2901c9
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/HdPsXxxControllerJoinMap.cs
@@ -0,0 +1,190 @@
+using System;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash_Essentials_Core.Bridges
+{
+ public class HdPsXxxControllerJoinMap : JoinMapBaseAdvanced
+ {
+
+ #region Digital
+
+ [JoinName("EnableAutoRoute")]
+ public JoinDataComplete EnableAutoRoute = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 1,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Enable Automatic Routing on Xx1 Switchers",
+ JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("InputSync")]
+ public JoinDataComplete InputSync = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 2,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "Device Input Sync",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("EnableInputHdcp")]
+ public JoinDataComplete EnableInputHdcp = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 11,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "Device Enable Input Hdcp",
+ JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("DisableInputHdcp")]
+ public JoinDataComplete DisableInputHdcp = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 21,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "Device Disnable Input Hdcp",
+ JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+
+ [JoinName("IsOnline")]
+ public JoinDataComplete IsOnline = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 30,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Device Onlne",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ #endregion
+
+
+ #region Analog
+
+ [JoinName("OutputRoute")]
+ public JoinDataComplete OutputRoute = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 11,
+ JoinSpan = 2
+ },
+ new JoinMetadata
+ {
+ Description = "Device Output Route Set/Get",
+ JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
+ JoinType = eJoinType.Analog
+ });
+
+ #endregion
+
+
+ #region Serial
+
+ [JoinName("Name")]
+ public JoinDataComplete Name = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 1,
+ JoinSpan = 1
+ },
+ new JoinMetadata
+ {
+ Description = "Device Name",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Serial
+ });
+
+
+ [JoinName("InputName")]
+ public JoinDataComplete InputName = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 2,
+ JoinSpan = 8
+ },
+ new JoinMetadata
+ {
+ Description = "Device Input Name",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Serial
+ });
+
+
+ [JoinName("OutputName")]
+ public JoinDataComplete OutputName = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 11,
+ JoinSpan = 2
+ },
+ new JoinMetadata
+ {
+ Description = "Device Output Name",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Serial
+ });
+
+
+ [JoinName("OutputRoutedName")]
+ public JoinDataComplete OutputRoutedName = new JoinDataComplete(
+ new JoinData
+ {
+ JoinNumber = 16,
+ JoinSpan = 2
+ },
+ new JoinMetadata
+ {
+ Description = "Device Output Route Name",
+ JoinCapabilities = eJoinCapabilities.ToSIMPL,
+ JoinType = eJoinType.Serial
+ });
+
+
+ #endregion
+
+ ///
+ /// Constructor to use when instantiating this join map without inheriting from it
+ ///
+ /// Join this join map will start at
+ public HdPsXxxControllerJoinMap(uint joinStart)
+ : this(joinStart, typeof(HdPsXxxControllerJoinMap))
+ {
+ }
+
+ ///
+ /// Constructor to use when extending this Join map
+ ///
+ /// Join this join map will start at
+ /// Type of the child join map
+ protected HdPsXxxControllerJoinMap(uint joinStart, Type type)
+ : base(joinStart, type)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IAnalogInputJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IAnalogInputJoinMap.cs
new file mode 100644
index 00000000..eaf70f3a
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IAnalogInputJoinMap.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace PepperDash.Essentials.Core.Bridges
+{
+ public class IAnalogInputJoinMap : JoinMapBaseAdvanced
+ {
+
+ [JoinName("InputValue")]
+ public JoinDataComplete InputValue = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "Input Value", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
+ [JoinName("MinimumChange")]
+ public JoinDataComplete MinimumChange = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
+ new JoinMetadata { Description = "Minimum voltage change required to reflect a change", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Analog });
+
+ ///
+ /// Constructor to use when instantiating this Join Map without inheriting from it
+ ///
+ /// Join this join map will start at
+ public IAnalogInputJoinMap(uint joinStart)
+ : this(joinStart, typeof(IAnalogInputJoinMap))
+ {
+ }
+
+ ///
+ /// Constructor to use when extending this Join map
+ ///
+ /// Join this join map will start at
+ /// Type of the child join map
+ protected IAnalogInputJoinMap(uint joinStart, Type type)
+ : base(joinStart, type)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs
index 085a33bd..83e6cdab 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalInputJoinMap.cs
@@ -1,13 +1,13 @@
using System;
-namespace PepperDash.Essentials.Core.Bridges
-{
- public class IDigitalInputJoinMap : JoinMapBaseAdvanced
- {
-
+namespace PepperDash.Essentials.Core.Bridges
+{
+ public class IDigitalInputJoinMap : JoinMapBaseAdvanced
+ {
+
[JoinName("InputState")]
public JoinDataComplete InputState = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
- new JoinMetadata { Description = "Room Email Url", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+ new JoinMetadata { Description = "Input State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
///
/// Constructor to use when instantiating this Join Map without inheriting from it
@@ -26,6 +26,6 @@ namespace PepperDash.Essentials.Core.Bridges
protected IDigitalInputJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
- }
- }
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalOutputJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalOutputJoinMap.cs
new file mode 100644
index 00000000..cbe62398
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/IDigitalOutputJoinMap.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace PepperDash.Essentials.Core.Bridges
+{
+ public class IDigitalOutputJoinMap : JoinMapBaseAdvanced
+ {
+
+ [JoinName("OutputState")]
+ public JoinDataComplete OutputState = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "Get / Set state of Digital Input", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ ///
+ /// Constructor to use when instantiating this Join Map without inheriting from it
+ ///
+ /// Join this join map will start at
+ public IDigitalOutputJoinMap(uint joinStart)
+ : this(joinStart, typeof(IDigitalOutputJoinMap))
+ {
+ }
+
+ ///
+ /// Constructor to use when extending this Join map
+ ///
+ /// Join this join map will start at
+ /// Type of the child join map
+ protected IDigitalOutputJoinMap(uint joinStart, Type type)
+ : base(joinStart, type)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/PduJoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/PduJoinMapBase.cs
index 2ac56ff1..0c2e9ed9 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/PduJoinMapBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/PduJoinMapBase.cs
@@ -10,7 +10,7 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("Online")]
public JoinDataComplete Online = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
- new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+ new JoinMetadata { Description = "Online", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletCount")]
public JoinDataComplete OutletCount = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs
index 363d389b..8e352bc5 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Bridges/JoinMaps/SystemMonitorJoinMap.cs
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Bridges
[JoinName("ProgramOffsetJoin")]
public JoinDataComplete ProgramOffsetJoin = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 5 },
new JoinMetadata { Description = "All Program Data is offset between slots by 5 - First Joins Start at 11", JoinCapabilities = eJoinCapabilities.None, JoinType = eJoinType.None });
-
+
[JoinName("ProgramStart")]
public JoinDataComplete ProgramStart = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Processor Program Start / Fb", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
@@ -132,6 +132,23 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete DhcpStatus = new JoinDataComplete(new JoinData { JoinNumber = 86, JoinSpan = 1 },
new JoinMetadata { Description = "Processor Ethernet Dhcp Status", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
+ [JoinName("ProcessorRebot")]
+ public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "Reboot processor", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("IsAppliance")]
+ public JoinDataComplete IsAppliance = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "Is appliance Fb", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("IsServer")]
+ public JoinDataComplete IsServer = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
+ new JoinMetadata { Description = "Is server Fb", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("ProgramReset")]
+ public JoinDataComplete ProgramReset = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 },
+ new JoinMetadata { Description = "Resets the program", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
+
///
/// Constructor to use when instantiating this Join Map without inheriting from it
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs
index 8a5efe47..d5bc56fe 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/CommFactory.cs
@@ -81,6 +81,15 @@ namespace PepperDash.Essentials.Core
}
case eControlMethod.Telnet:
break;
+ case eControlMethod.SecureTcpIp:
+ {
+ var secureTcp = new GenericSecureTcpIpClient(deviceConfig.Key + "-secureTcp", c.Address, c.Port, c.BufferSize);
+ secureTcp.AutoReconnect = c.AutoReconnect;
+ if (secureTcp.AutoReconnect)
+ secureTcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
+ comm = secureTcp;
+ break;
+ }
default:
break;
}
@@ -115,41 +124,54 @@ namespace PepperDash.Essentials.Core
///
public static ICec GetCecPort(ControlPropertiesConfig config)
{
- var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
+ try
+ {
+ var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
- if (dev != null)
- {
- if (!String.IsNullOrEmpty(config.ControlPortName))
- {
+ Debug.Console(0, "GetCecPort: device '{0}' {1}", config.ControlPortDevKey, dev == null
+ ? "is not valid, failed to get cec port"
+ : "found in device manager, attempting to get cec port");
- var inputPort = (dev as IRoutingInputsOutputs).InputPorts[config.ControlPortName];
+ if (dev == null)
+ return null;
- if (inputPort != null)
- {
- if (inputPort.Port is ICec)
- return inputPort.Port as ICec;
- }
+ if (String.IsNullOrEmpty(config.ControlPortName))
+ {
+ Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
+ return null;
+ }
- var outputPort = (dev as IRoutingInputsOutputs).OutputPorts[config.ControlPortName];
- if (outputPort != null)
- {
- if (outputPort.Port is ICec)
- return outputPort.Port as ICec;
- }
+ var inputsOutputs = dev as IRoutingInputsOutputs;
+ if (inputsOutputs == null)
+ {
+ Debug.Console(0, "GetCecPort: Device '{0}' does not support IRoutingInputsOutputs, failed to get CEC port called '{1}'",
+ config.ControlPortDevKey, config.ControlPortName);
- else
- Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called: '{1}'",
- config.ControlPortDevKey, config.ControlPortName);
- }
- else
- {
- Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
- }
- }
- Debug.Console(0, "GetCecPort: Device '{0}' is not a valid device.", config.ControlPortDevKey);
+ return null;
+ }
- return null;
+ var inputPort = inputsOutputs.InputPorts[config.ControlPortName];
+ if (inputPort != null && inputPort.Port is ICec)
+ return inputPort.Port as ICec;
+
+
+ var outputPort = inputsOutputs.OutputPorts[config.ControlPortName];
+ if (outputPort != null && outputPort.Port is ICec)
+ return outputPort.Port as ICec;
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(1, "GetCecPort Exception Message: {0}", ex.Message);
+ Debug.Console(2, "GetCecPort Exception StackTrace: {0}", ex.StackTrace);
+ if (ex.InnerException != null)
+ Debug.Console(0, "GetCecPort Exception InnerException: {0}", ex.InnerException);
+ }
+
+ Debug.Console(0, "GetCecPort: Device '{0}' does not have a CEC port called '{1}'",
+ config.ControlPortDevKey, config.ControlPortName);
+
+ return null;
}
///
@@ -183,6 +205,8 @@ namespace PepperDash.Essentials.Core
[JsonConverter(typeof(ComSpecJsonConverter))]
public ComPort.ComPortSpec ComParams { get; set; }
+ public string RoomId { get; set; }
+
public string CresnetId { get; set; }
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/IRPortHelper.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/IRPortHelper.cs
index c75630e4..80ee2a2c 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/IRPortHelper.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Comm and IR/IRPortHelper.cs
@@ -224,12 +224,18 @@ namespace PepperDash.Essentials.Core
///
public class IrOutPortConfig
{
+ [JsonProperty("port")]
public IROutputPort Port { get; set; }
+
+ [JsonProperty("fileName")]
public string FileName { get; set; }
+ [JsonProperty("useBridgeJoinMap")]
+ public bool UseBridgeJoinMap { get; set; }
+
public IrOutPortConfig()
{
- FileName = "";
+ FileName = "";
}
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs
new file mode 100644
index 00000000..bbd496b4
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/CenIoCom/CenIoComController.cs
@@ -0,0 +1,85 @@
+using System.Collections.Generic;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.GeneralIO;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Config;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ ///
+ /// Wrapper class for CEN-IO-COM-Xxx expander module
+ ///
+ [Description("Wrapper class for the CEN-IO-COM-102 & CEN-IO-COM-202 expander module")]
+ public class CenIoComController : CrestronGenericBaseDevice, IComPorts
+ {
+ private readonly CenIoCom _cenIoCom;
+
+ public CenIoComController(string key, string name, CenIoCom cenIo)
+ :base(key, name, cenIo)
+ {
+ _cenIoCom = cenIo;
+ }
+
+ #region Implementation of IComPorts
+
+ public CrestronCollection ComPorts
+ {
+ get { return _cenIoCom.ComPorts; }
+ }
+
+ public int NumberOfComPorts
+ {
+ get { return _cenIoCom.NumberOfComPorts; }
+ }
+
+ #endregion
+
+ }
+
+ public class CenIoCom102ControllerFactory : EssentialsDeviceFactory
+ {
+ private const string CenIoCom102Type = "ceniocom102";
+ private const string CenIoCom202Type = "ceniocom202";
+
+ public CenIoCom102ControllerFactory()
+ {
+ TypeNames = new List { CenIoCom102Type, CenIoCom202Type };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new CEN-IO-COM-Xxx Device");
+
+ var control = CommFactory.GetControlPropertiesConfig(dc);
+ if (control == null)
+ {
+ Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, control properties not found");
+ return null;
+ }
+
+ var ipid = control.IpIdInt;
+ if (ipid < 2)
+ {
+ Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, invalid IP-ID found");
+ return null;
+ }
+
+ switch (dc.Type)
+ {
+ case CenIoCom102Type:
+ {
+ return new CenIoComController(dc.Key, dc.Name, new CenIoCom102(ipid, Global.ControlSystem));
+ }
+ case CenIoCom202Type:
+ {
+ return new CenIoComController(dc.Key, dc.Name, new CenIoCom202(ipid, Global.ControlSystem));
+ }
+ default:
+ {
+ Debug.Console(1, "Factory failed to create a new CEN-IO-COM-Xxx Device, invalid type '{0}'", dc.Type);
+ return null;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/DinIo8/DinIo8Controller.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/DinIo8/DinIo8Controller.cs
new file mode 100644
index 00000000..794fe609
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/DinIo8/DinIo8Controller.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.GeneralIO;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.Core.Config;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ public class DinIo8Controller:CrestronGenericBaseDevice, IIOPorts
+ {
+ private DinIo8 _device;
+
+ public DinIo8Controller(string key, Func preActivationFunc, DeviceConfig config):base(key, config.Name)
+ {
+ AddPreActivationAction(() =>
+ {
+ _device = preActivationFunc(config);
+
+ RegisterCrestronGenericBase(_device);
+ });
+ }
+
+ #region Implementation of IIOPorts
+
+ public CrestronCollection VersiPorts
+ {
+ get { return _device.VersiPorts; }
+ }
+
+ public int NumberOfVersiPorts
+ {
+ get { return _device.NumberOfVersiPorts; }
+ }
+
+ #endregion
+
+
+ }
+
+ public class DinIo8ControllerFactory : EssentialsDeviceFactory
+ {
+ public DinIo8ControllerFactory()
+ {
+ TypeNames = new List() { "DinIo8" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new DinIo8 Device");
+
+ return new DinIo8Controller(dc.Key, GetDinIo8Device, dc);
+ }
+
+ static DinIo8 GetDinIo8Device(DeviceConfig dc)
+ {
+ var control = CommFactory.GetControlPropertiesConfig(dc);
+ var cresnetId = control.CresnetIdInt;
+ var branchId = control.ControlPortNumber;
+ var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
+
+ if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
+ {
+ Debug.Console(0, "Device {0} is a valid cresnet master - creating new DinIo8", parentKey);
+ return new DinIo8(cresnetId, Global.ControlSystem);
+ }
+ var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
+
+ if (cresnetBridge != null)
+ {
+ Debug.Console(0, "Device {0} is a valid cresnet master - creating new DinIo8", parentKey);
+ return new DinIo8(cresnetId, cresnetBridge.CresnetBranches[branchId]);
+ }
+ Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/IOPortConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/IOPortConfig.cs
index 09061ff2..5fbe10e1 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/IOPortConfig.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/IOPortConfig.cs
@@ -15,5 +15,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
public uint PortNumber { get; set; }
[JsonProperty("disablePullUpResistor")]
public bool DisablePullUpResistor { get; set; }
+ [JsonProperty("minimumChange")]
+ public int MinimumChange { get; set; }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportAnalogInputDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportAnalogInputDevice.cs
new file mode 100644
index 00000000..70be2f6f
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/GenericVersiportAnalogInputDevice.cs
@@ -0,0 +1,208 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.Bridges;
+
+
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ ///
+ /// Represents a generic digital input deviced tied to a versiport
+ ///
+ public class GenericVersiportAnalogInputDevice : EssentialsBridgeableDevice, IAnalogInput
+ {
+ public Versiport InputPort { get; private set; }
+
+ public IntFeedback InputValueFeedback { get; private set; }
+ public IntFeedback InputMinimumChangeFeedback { get; private set; }
+
+ Func InputValueFeedbackFunc
+ {
+ get
+ {
+ return () => InputPort.AnalogIn;
+ }
+ }
+
+ Func InputMinimumChangeFeedbackFunc
+ {
+ get { return () => InputPort.AnalogMinChange; }
+ }
+
+ public GenericVersiportAnalogInputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) :
+ base(key, name)
+ {
+ InputValueFeedback = new IntFeedback(InputValueFeedbackFunc);
+ InputMinimumChangeFeedback = new IntFeedback(InputMinimumChangeFeedbackFunc);
+
+ AddPostActivationAction(() =>
+ {
+ InputPort = postActivationFunc(config);
+
+ InputPort.Register();
+
+ InputPort.SetVersiportConfiguration(eVersiportConfiguration.AnalogInput);
+ InputPort.AnalogMinChange = (ushort)(config.MinimumChange > 0 ? config.MinimumChange : 655);
+ if (config.DisablePullUpResistor)
+ InputPort.DisablePullUpResistor = true;
+
+ InputPort.VersiportChange += InputPort_VersiportChange;
+
+ Debug.Console(1, this, "Created GenericVersiportAnalogInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
+
+ });
+
+ }
+
+ ///
+ /// Set minimum voltage change for device to update voltage changed method
+ ///
+ /// valid values range from 0 - 65535, representing the full 100% range of the processor voltage source. Check processor documentation for details
+ public void SetMinimumChange(ushort value)
+ {
+ InputPort.AnalogMinChange = value;
+ }
+
+ void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
+ {
+ Debug.Console(1, this, "Versiport change: {0}", args.Event);
+
+ if(args.Event == eVersiportEvent.AnalogInChange)
+ InputValueFeedback.FireUpdate();
+ if (args.Event == eVersiportEvent.AnalogMinChangeChange)
+ InputMinimumChangeFeedback.FireUpdate();
+ }
+
+
+ #region Bridge Linking
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new IAnalogInputJoinMap(joinStart);
+
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!string.IsNullOrEmpty(joinMapSerialized))
+ joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ else
+ {
+ Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
+ }
+
+ try
+ {
+ Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ // Link feedback for input state
+ InputValueFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputValue.JoinNumber]);
+ InputMinimumChangeFeedback.LinkInputSig(trilist.UShortInput[joinMap.MinimumChange.JoinNumber]);
+ trilist.SetUShortSigAction(joinMap.MinimumChange.JoinNumber, SetMinimumChange);
+
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
+ Debug.Console(1, this, "Error: {0}", e);
+ }
+
+ trilist.OnlineStatusChange += (d, args) =>
+ {
+ if (!args.DeviceOnLine) return;
+ InputValueFeedback.FireUpdate();
+ InputMinimumChangeFeedback.FireUpdate();
+ };
+
+ }
+
+ void trilist_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+
+
+ public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
+ {
+
+ IIOPorts ioPortDevice;
+
+ if (dc.PortDeviceKey.Equals("processor"))
+ {
+ if (!Global.ControlSystem.SupportsVersiport)
+ {
+ Debug.Console(0, "GetVersiportAnalogInput: Processor does not support Versiports");
+ return null;
+ }
+ ioPortDevice = Global.ControlSystem;
+ }
+ else
+ {
+ var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
+ if (ioPortDev == null)
+ {
+ Debug.Console(0, "GetVersiportAnalogInput: Device {0} is not a valid device", dc.PortDeviceKey);
+ return null;
+ }
+ ioPortDevice = ioPortDev;
+ }
+ if (ioPortDevice == null)
+ {
+ Debug.Console(0, "GetVersiportAnalogInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
+ return null;
+ }
+
+ if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
+ {
+ Debug.Console(0, "GetVersiportAnalogInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
+ return null;
+ }
+ if(!ioPortDevice.VersiPorts[dc.PortNumber].SupportsAnalogInput)
+ {
+ Debug.Console(0, "GetVersiportAnalogInput: Device {0} does not support AnalogInput on port {1}", dc.PortDeviceKey, dc.PortNumber);
+ return null;
+ }
+
+
+ return ioPortDevice.VersiPorts[dc.PortNumber];
+
+
+ }
+ }
+
+
+ public class GenericVersiportAbalogInputDeviceFactory : EssentialsDeviceFactory
+ {
+ public GenericVersiportAbalogInputDeviceFactory()
+ {
+ TypeNames = new List() { "versiportanaloginput" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new Generic Versiport Device");
+
+ var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
+
+ if (props == null) return null;
+
+ var portDevice = new GenericVersiportAnalogInputDevice(dc.Key, dc.Name, GenericVersiportAnalogInputDevice.GetVersiportDigitalInput, props);
+
+ return portDevice;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/IAnalogInput.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/IAnalogInput.cs
new file mode 100644
index 00000000..44af9954
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Inputs/IAnalogInput.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ public interface IAnalogInput
+ {
+ IntFeedback InputValueFeedback { get; }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/GenericVersiportOutputDevice.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/GenericVersiportOutputDevice.cs
new file mode 100644
index 00000000..2d1ae9c4
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/GenericVersiportOutputDevice.cs
@@ -0,0 +1,189 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Config;
+using PepperDash.Essentials.Core.Bridges;
+
+
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ ///
+ /// Represents a generic digital input deviced tied to a versiport
+ ///
+ public class GenericVersiportDigitalOutputDevice : EssentialsBridgeableDevice, IDigitalOutput
+ {
+ public Versiport OutputPort { get; private set; }
+
+ public BoolFeedback OutputStateFeedback { get; private set; }
+
+ Func OutputStateFeedbackFunc
+ {
+ get
+ {
+ return () => OutputPort.DigitalOut;
+ }
+ }
+
+ public GenericVersiportDigitalOutputDevice(string key, string name, Func postActivationFunc, IOPortConfig config) :
+ base(key, name)
+ {
+ OutputStateFeedback = new BoolFeedback(OutputStateFeedbackFunc);
+
+ AddPostActivationAction(() =>
+ {
+ OutputPort = postActivationFunc(config);
+
+ OutputPort.Register();
+
+
+ if (!OutputPort.SupportsDigitalOutput)
+ {
+ Debug.Console(0, this, "Device does not support configuration as a Digital Output");
+ return;
+ }
+
+ OutputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalOutput);
+
+
+ OutputPort.VersiportChange += OutputPort_VersiportChange;
+
+ });
+
+ }
+
+ void OutputPort_VersiportChange(Versiport port, VersiportEventArgs args)
+ {
+ Debug.Console(1, this, "Versiport change: {0}", args.Event);
+
+ if(args.Event == eVersiportEvent.DigitalOutChange)
+ OutputStateFeedback.FireUpdate();
+ }
+
+ ///
+ /// Set value of the versiport digital output
+ ///
+ /// value to set the output to
+ public void SetOutput(bool state)
+ {
+ if (OutputPort.SupportsDigitalOutput)
+ {
+ Debug.Console(0, this, "Passed the Check");
+
+ OutputPort.DigitalOut = state;
+
+ }
+ else
+ {
+ Debug.Console(0, this, "Versiport does not support Digital Output Mode");
+ }
+
+ }
+
+ #region Bridge Linking
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new IDigitalOutputJoinMap(joinStart);
+
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!string.IsNullOrEmpty(joinMapSerialized))
+ joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ else
+ {
+ Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
+ }
+
+ try
+ {
+ Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ // Link feedback for input state
+ OutputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OutputState.JoinNumber]);
+ trilist.SetBoolSigAction(joinMap.OutputState.JoinNumber, SetOutput);
+ }
+ catch (Exception e)
+ {
+ Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
+ Debug.Console(1, this, "Error: {0}", e);
+ }
+ }
+
+ #endregion
+
+
+ public static Versiport GetVersiportDigitalOutput(IOPortConfig dc)
+ {
+
+ IIOPorts ioPortDevice;
+
+ if (dc.PortDeviceKey.Equals("processor"))
+ {
+ if (!Global.ControlSystem.SupportsVersiport)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Processor does not support Versiports");
+ return null;
+ }
+ ioPortDevice = Global.ControlSystem;
+ }
+ else
+ {
+ var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
+ if (ioPortDev == null)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Device {0} is not a valid device", dc.PortDeviceKey);
+ return null;
+ }
+ ioPortDevice = ioPortDev;
+ }
+ if (ioPortDevice == null)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Device '0' is not a valid IOPorts Device", dc.PortDeviceKey);
+ return null;
+ }
+
+ if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
+ {
+ Debug.Console(0, "GetVersiportDigitalOuptut: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
+ }
+ var port = ioPortDevice.VersiPorts[dc.PortNumber];
+ return port;
+
+ }
+ }
+
+
+ public class GenericVersiportDigitalOutputDeviceFactory : EssentialsDeviceFactory
+ {
+ public GenericVersiportDigitalOutputDeviceFactory()
+ {
+ TypeNames = new List() { "versiportoutput" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new Generic Versiport Device");
+
+ var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
+
+ if (props == null) return null;
+
+ var portDevice = new GenericVersiportDigitalOutputDevice(dc.Key, dc.Name, GenericVersiportDigitalOutputDevice.GetVersiportDigitalOutput, props);
+
+ return portDevice;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/IDigitalOutput.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/IDigitalOutput.cs
new file mode 100644
index 00000000..b4151941
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Crestron IO/Outputs/IDigitalOutput.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+
+namespace PepperDash.Essentials.Core.CrestronIO
+{
+ ///
+ /// Represents a device that provides digital input
+ ///
+ public interface IDigitalOutput
+ {
+ BoolFeedback OutputStateFeedback { get; }
+ void SetOutput(bool state);
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs
new file mode 100644
index 00000000..04e697c9
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Device Info/NetworkDeviceHelpers.cs
@@ -0,0 +1,218 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using PepperDash.Core;
+using Crestron.SimplSharp;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.Core.DeviceInfo
+{
+ public static class NetworkDeviceHelpers
+ {
+ ///
+ /// Event raised when ArpTable changes
+ ///
+ public static event ArpTableEventHandler ArpTableUpdated;
+
+ ///
+ /// Delegate called by ArpTableUpdated
+ ///
+ /// contains the entire ARP table and a bool to note if there was an error in retrieving the data
+ public delegate void ArpTableEventHandler(ArpTableEventArgs args);
+
+ private static readonly char NewLineSplitter = CrestronEnvironment.NewLine.ToCharArray().First();
+ private static readonly string NewLine = CrestronEnvironment.NewLine;
+
+ private static readonly CCriticalSection Lock = new CCriticalSection();
+
+ ///
+ /// Last resolved ARP table - it is recommended to refresh the arp before using this.
+ ///
+ public static List ArpTable { get; private set; }
+
+ ///
+ /// Force recheck of ARP table
+ ///
+ public static void RefreshArp()
+ {
+ var error = false;
+ try
+ {
+ Lock.Enter();
+ var consoleResponse = string.Empty;
+ if (!CrestronConsole.SendControlSystemCommand("showarptable", ref consoleResponse)) return;
+ if (string.IsNullOrEmpty(consoleResponse))
+ {
+ error = true;
+ return;
+ }
+ ArpTable.Clear();
+
+ Debug.Console(2, "ConsoleResponse of 'showarptable' : {0}{1}", NewLine, consoleResponse);
+
+ var myLines =
+ consoleResponse.Split(NewLineSplitter)
+ .ToList()
+ .Where(o => (o.Contains(':') && !o.Contains("Type", StringComparison.OrdinalIgnoreCase)))
+ .ToList();
+ foreach (var line in myLines)
+ {
+ var item = line;
+ var seperator = item.Contains('\t') ? '\t' : ' ';
+ var dataPoints = item.Split(seperator);
+ if (dataPoints == null || dataPoints.Length < 2) continue;
+ var ipAddress = SanitizeIpAddress(dataPoints.First().TrimAll());
+ var macAddress = dataPoints.Last();
+ ArpTable.Add(new ArpEntry(ipAddress, macAddress));
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, "Exception in \"RefreshArp\" : {0}", ex.Message);
+ error = true;
+ }
+ finally
+ {
+ Lock.Leave();
+ OnArpTableUpdated(new ArpTableEventArgs(ArpTable, error));
+ }
+ }
+
+
+ private static void OnArpTableUpdated(ArpTableEventArgs args)
+ {
+ if (args == null) return;
+ var handler = ArpTableUpdated;
+ if (handler == null) return;
+ handler.Invoke(args);
+ }
+
+ static NetworkDeviceHelpers()
+ {
+ ArpTable = new List();
+ }
+
+ ///
+ /// Removes leading zeros, leading whitespace, and trailing whitespace from an IPAddress string
+ ///
+ /// Ip Address to Santitize
+ /// Sanitized Ip Address
+ public static string SanitizeIpAddress(string ipAddressIn)
+ {
+ try
+ {
+ var ipAddress = IPAddress.Parse(ipAddressIn.TrimStart('0'));
+ return ipAddress.ToString();
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, "Unable to Santize Ip : {0}", ex.Message);
+ return ipAddressIn;
+ }
+ }
+
+ ///
+ /// Resolves a hostname by IP Address using DNS
+ ///
+ /// IP Address to resolve from
+ /// Resolved Hostname - on failure to determine hostname, will return IP Address
+ public static string ResolveHostnameFromIp(string ipAddress)
+ {
+ try
+ {
+ var santitizedIp = SanitizeIpAddress(ipAddress);
+ var hostEntry = Dns.GetHostEntry(santitizedIp);
+ return hostEntry == null ? ipAddress : hostEntry.HostName;
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, "Exception Resolving Hostname from IP Address : {0}", ex.Message);
+ return ipAddress;
+ }
+ }
+
+ ///
+ /// Resolves an IP Address by hostname using DNS
+ ///
+ /// Hostname to resolve from
+ /// Resolved IP Address - on a failure to determine IP Address, will return hostname
+ public static string ResolveIpFromHostname(string hostName)
+ {
+ try
+ {
+ var hostEntry = Dns.GetHostEntry(hostName);
+ return hostEntry == null ? hostName : hostEntry.AddressList.First().ToString();
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, "Exception Resolving IP Address from Hostname : {0}", ex.Message);
+ return hostName;
+ }
+ }
+
+ }
+
+ ///
+ /// Object to hold data about an arp entry
+ ///
+ public class ArpEntry
+ {
+ public readonly IPAddress IpAddress;
+ public readonly string MacAddress;
+
+ ///
+ /// Constructs new ArpEntry object
+ ///
+ /// string formatted as ipv4 address
+ /// mac address string - format is unimportant
+ public ArpEntry(string ipAddress, string macAddress)
+ {
+ if (string.IsNullOrEmpty(ipAddress))
+ {
+ throw new ArgumentException("\"ipAddress\" cannot be null or empty");
+ }
+ if (string.IsNullOrEmpty(macAddress))
+ {
+ throw new ArgumentException("\"macAddress\" cannot be null or empty");
+ }
+ IpAddress = IPAddress.Parse(ipAddress.TrimStart().TrimStart('0').TrimEnd());
+ MacAddress = macAddress;
+ }
+ }
+
+ ///
+ /// Arguments passed by the ArpTableUpdated event
+ ///
+ public class ArpTableEventArgs : EventArgs
+ {
+ ///
+ /// The retrieved ARP Table
+ ///
+ public readonly List ArpTable;
+ ///
+ /// True if there was a problem retrieving the ARP Table
+ ///
+ public readonly bool Error;
+
+ ///
+ /// Constructor for ArpTableEventArgs
+ ///
+ /// The entirety of the retrieved ARP table
+ /// True of an error was encountered updating the ARP table
+ public ArpTableEventArgs(List arpTable, bool error)
+ {
+ ArpTable = arpTable;
+ Error = error;
+ }
+
+ ///
+ /// Constructor for ArpTableEventArgs - assumes no error encountered in retrieving ARP Table
+ ///
+ /// The entirety of the retrieved ARP table
+ public ArpTableEventArgs(List arpTable)
+ {
+ ArpTable = arpTable;
+ Error = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs
index 57bf2287..55237496 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/DeviceManager.cs
@@ -379,30 +379,28 @@ namespace PepperDash.Essentials.Core
/// Prints a list of routing inputs and outputs by device key.
///
/// Device key from which to report data
- public static void GetRoutingPorts(string s)
- {
- var device = GetDeviceForKey(s);
+ public static void GetRoutingPorts(string s)
+ {
+ var device = GetDeviceForKey(s);
if (device == null) return;
var inputPorts = ((device as IRoutingInputs) != null) ? (device as IRoutingInputs).InputPorts : null;
var outputPorts = ((device as IRoutingOutputs) != null) ? (device as IRoutingOutputs).OutputPorts : null;
- if (inputPorts != null)
- {
- Debug.Console(0, "Device {0} has {1} Input Ports:", s, inputPorts.Count);
- foreach (var routingInputPort in inputPorts)
- {
- Debug.Console(0, "{0}", routingInputPort.Key);
- }
- }
- if (outputPorts != null)
- {
- Debug.Console(0, "Device {0} has {1} Output Ports:", s, outputPorts.Count);
- foreach (var routingOutputPort in outputPorts)
- {
- Debug.Console(0, "{0}", routingOutputPort.Key);
- }
- }
- }
+ if (inputPorts != null)
+ {
+ CrestronConsole.ConsoleCommandResponse("Device {0} has {1} Input Ports:{2}", s, inputPorts.Count, CrestronEnvironment.NewLine);
+ foreach (var routingInputPort in inputPorts)
+ {
+ CrestronConsole.ConsoleCommandResponse("{0}{1}", routingInputPort.Key, CrestronEnvironment.NewLine);
+ }
+ }
+ if (outputPorts == null) return;
+ CrestronConsole.ConsoleCommandResponse("Device {0} has {1} Output Ports:{2}", s, outputPorts.Count, CrestronEnvironment.NewLine);
+ foreach (var routingOutputPort in outputPorts)
+ {
+ CrestronConsole.ConsoleCommandResponse("{0}{1}", routingOutputPort.Key, CrestronEnvironment.NewLine);
+ }
+ }
///
/// Attempts to set the debug level of a device
@@ -435,7 +433,7 @@ namespace PepperDash.Essentials.Core
if (device == null)
{
- Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
+ CrestronConsole.ConsoleCommandResponse("Unable to get device with key: {0}", deviceKey);
return;
}
@@ -447,7 +445,7 @@ namespace PepperDash.Essentials.Core
}
catch
{
- Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
+ CrestronConsole.ConsoleCommandResponse("Unable to convert setting value. Please use off/rx/tx/both");
return;
}
@@ -458,18 +456,18 @@ namespace PepperDash.Essentials.Core
var min = Convert.ToUInt32(timeout);
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
- Debug.Console(0, "Device: '{0}' debug level set to {1} for {2} minutes", deviceKey, debugSetting, min);
+ CrestronConsole.ConsoleCommandResponse("Device: '{0}' debug level set to {1} for {2} minutes", deviceKey, debugSetting, min);
}
catch (Exception e)
{
- Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
+ CrestronConsole.ConsoleCommandResponse("Unable to convert minutes or settings value. Please use an integer value for minutes. Error: {0}", e);
}
}
else
{
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
- Debug.Console(0, "Device: '{0}' debug level set to {1} for default time (30 minutes)", deviceKey, debugSetting);
+ CrestronConsole.ConsoleCommandResponse("Device: '{0}' debug level set to {1} for default time (30 minutes)", deviceKey, debugSetting);
}
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs
index 409562a2..df76b726 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/GenericIRController.cs
@@ -1,11 +1,11 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
+using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
-using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
+using PepperDash_Essentials_Core.Bridges.JoinMaps;
namespace PepperDash.Essentials.Core.Devices
{
@@ -19,12 +19,11 @@ namespace PepperDash.Essentials.Core.Devices
private readonly IrOutputPortController _port;
- public string[] IrCommands {get { return _port.IrFileCommands; }}
+ public string[] IrCommands {get { return _port.IrFileCommands; }}
public GenericIrController(string key, string name, IrOutputPortController irPort) : base(key, name)
{
_port = irPort;
-
if (_port == null)
{
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "IR Port is null, device will not function");
@@ -71,23 +70,65 @@ namespace PepperDash.Essentials.Core.Devices
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
- for (uint i = 0; i < _port.IrFileCommands.Length; i++)
- {
- var cmd = _port.IrFileCommands[i];
- var joinData = new JoinDataComplete(new JoinData {JoinNumber = i, JoinSpan = 1},
- new JoinMetadata
- {
- Description = cmd,
- JoinCapabilities = eJoinCapabilities.FromSIMPL,
- JoinType = eJoinType.Digital
- });
+ if (_port.UseBridgeJoinMap)
+ {
+ Debug.Console(0, this, "Using new IR bridge join map");
- joinData.SetJoinOffset(joinStart);
+ var bridgeJoins = joinMap.Joins.Where((kv) => _port.IrFileCommands.Any(cmd => cmd == kv.Key)).ToDictionary(kv => kv.Key);
+ if (bridgeJoins == null)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Failed to link new IR bridge join map");
+ return;
+ }
- joinMap.Joins.Add(cmd,joinData);
+ joinMap.Joins.Clear();
- trilist.SetBoolSigAction(joinData.JoinNumber, (b) => Press(cmd, b));
- }
+ foreach (var bridgeJoin in bridgeJoins)
+ {
+ var key = bridgeJoin.Key;
+ var joinDataKey = bridgeJoin.Value.Key;
+ var joinDataValue = bridgeJoin.Value.Value;
+ var joinNumber = bridgeJoin.Value.Value.JoinNumber;
+
+ Debug.Console(2, this, @"bridgeJoin: Key-'{0}'
+Value.Key-'{1}'
+Value.JoinNumber-'{2}'
+Value.Metadata.Description-'{3}'",
+ key,
+ joinDataKey,
+ joinNumber,
+ joinDataValue.Metadata.Description);
+
+
+ joinMap.Joins.Add(key, joinDataValue);
+
+ trilist.SetBoolSigAction(joinNumber, (b) => Press(key, b));
+ }
+ }
+ else
+ {
+ Debug.Console(0, this, "Using legacy IR join mapping based on available IR commands");
+
+ joinMap.Joins.Clear();
+
+ for (uint i = 0; i < _port.IrFileCommands.Length; i++)
+ {
+ var cmd = _port.IrFileCommands[i];
+ var joinData = new JoinDataComplete(new JoinData { JoinNumber = i, JoinSpan = 1 },
+ new JoinMetadata
+ {
+ Description = cmd,
+ JoinCapabilities = eJoinCapabilities.FromSIMPL,
+ JoinType = eJoinType.Digital
+ });
+
+ joinData.SetJoinOffset(joinStart);
+
+ joinMap.Joins.Add(cmd, joinData);
+
+ trilist.SetBoolSigAction(joinData.JoinNumber, (b) => Press(cmd, b));
+ }
+ }
joinMap.PrintJoinMapInfo();
@@ -109,13 +150,6 @@ namespace PepperDash.Essentials.Core.Devices
}
}
- public sealed class GenericIrControllerJoinMap : JoinMapBaseAdvanced
- {
- public GenericIrControllerJoinMap(uint joinStart) : base(joinStart)
- {
- }
- }
-
public class GenericIrControllerFactory : EssentialsDeviceFactory
{
public GenericIrControllerFactory()
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs
index c8a5df39..c8033b92 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IVolumeAndAudioInterfaces.cs
@@ -72,6 +72,10 @@ namespace PepperDash.Essentials.Core
{
IBasicVolumeControls CurrentVolumeControls { get; }
event EventHandler CurrentVolumeDeviceChange;
+
+ void SetDefaultLevels();
+
+ bool ZeroVolumeWhenSwtichingVolumeDevices { get; }
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs
index cce1d46e..d404b3ea 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/IrOutputPortController.cs
@@ -29,6 +29,8 @@ namespace PepperDash.Essentials.Core
public string[] IrFileCommands { get { return IrPort.AvailableStandardIRCmds(IrPortUid); } }
+ public bool UseBridgeJoinMap { get; private set; }
+
///
/// Constructor for IrDevice base class. If a null port is provided, this class will
/// still function without trying to talk to a port.
@@ -53,9 +55,10 @@ namespace PepperDash.Essentials.Core
: base(key)
{
DriverLoaded = new BoolFeedback(() => DriverIsLoaded);
+ UseBridgeJoinMap = config.Properties["control"].Value("useBridgeJoinMap");
AddPostActivationAction(() =>
{
- IrPort = postActivationFunc(config);
+ IrPort = postActivationFunc(config);
if (IrPort == null)
{
@@ -67,8 +70,8 @@ namespace PepperDash.Essentials.Core
Debug.Console(1, "*************Attempting to load IR file: {0}***************", filePath);
LoadDriver(filePath);
-
- PrintAvailableCommands();
+
+ PrintAvailableCommands();
});
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PduInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PduInterfaces.cs
index 0f3b3fbf..94aa71ac 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PduInterfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PduInterfaces.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
@@ -8,6 +9,7 @@ namespace PepperDash_Essentials_Core.Devices
///
/// Interface for any device that is able to control it'spower and has a configurable reboot time
///
+ [Obsolete("PepperDash_Essentials_Core.Devices is Deprecated - use PepperDash.Essentials.Core")]
public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
{
///
@@ -24,6 +26,7 @@ namespace PepperDash_Essentials_Core.Devices
///
/// Interface for any device that contains a collection of IHasPowerReboot Devices
///
+ [Obsolete("PepperDash_Essentials_Core.Devices is Deprecated - use PepperDash.Essentials.Core")]
public interface IHasControlledPowerOutlets : IKeyName
{
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PowerInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PowerInterfaces.cs
new file mode 100644
index 00000000..1fc6672a
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/PowerInterfaces.cs
@@ -0,0 +1,87 @@
+using Crestron.SimplSharp;
+using PepperDash.Core;
+
+namespace PepperDash.Essentials.Core
+{
+ ///
+ /// Interface for any device that has a battery that can be monitored
+ ///
+ public interface IHasBatteryStats : IKeyName
+ {
+ int BatteryPercentage { get; }
+ int BatteryCautionThresholdPercentage { get; }
+ int BatteryWarningThresholdPercentage { get; }
+ BoolFeedback BatteryIsWarningFeedback { get; }
+ BoolFeedback BatteryIsCautionFeedback { get; }
+ BoolFeedback BatteryIsOkFeedback { get; }
+ IntFeedback BatteryPercentageFeedback { get; }
+ }
+
+ ///
+ /// Interface for any device that has a battery that can be monitored and the ability to charge and discharge
+ ///
+ public interface IHasBatteryCharging : IHasBatteryStats
+ {
+ BoolFeedback BatteryIsCharging { get; }
+ }
+
+ ///
+ /// Interface for any device that has multiple batteries that can be monitored
+ ///
+ public interface IHasBatteries : IKeyName
+ {
+ ReadOnlyDictionary Batteries { get; }
+ }
+
+ public interface IHasBatteryStatsExtended : IHasBatteryStats
+ {
+ int InputVoltage { get; }
+ int OutputVoltage { get; }
+ int InptuCurrent { get; }
+ int OutputCurrent { get; }
+
+ IntFeedback InputVoltageFeedback { get; }
+ IntFeedback OutputVoltageFeedback { get; }
+ IntFeedback InputCurrentFeedback { get; }
+ IntFeedback OutputCurrentFeedback { get; }
+ }
+
+ ///
+ /// Interface for any device that is able to control its power, has a configurable reboot time, and has batteries that can be monitored
+ ///
+ public interface IHasPowerCycleWithBattery : IHasPowerCycle, IHasBatteryStats
+ {
+
+ }
+
+ ///
+ /// Interface for any device that is able to control it's power and has a configurable reboot time
+ ///
+ public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
+ {
+ ///
+ /// Delay between power off and power on for reboot
+ ///
+ int PowerCycleTimeMs { get; }
+
+ ///
+ /// Reboot outlet
+ ///
+ void PowerCycle();
+ }
+
+ ///
+ /// Interface for any device that contains a collection of IHasPowerReboot Devices
+ ///
+ public interface IHasControlledPowerOutlets : IKeyName
+ {
+ ///
+ /// Collection of IPduOutlets
+ ///
+ ReadOnlyDictionary PduOutlets { get; }
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs
index 708ed930..7bf8d5a5 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Extensions/StringExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -8,13 +9,70 @@ namespace PepperDash.Essentials.Core
{
public static class StringExtensions
{
+ ///
+ /// Returns null if a string is empty, otherwise returns the string
+ ///
+ /// string input
+ /// null if the string is emtpy, otherwise returns the string
public static string NullIfEmpty(this string s)
{
return string.IsNullOrEmpty(s) ? null : s;
}
+
+ ///
+ /// Returns null if a string is empty or made of only whitespace characters, otherwise returns the string
+ ///
+ /// string input
+ /// null if the string is wempty or made of only whitespace characters, otherwise returns the string
public static string NullIfWhiteSpace(this string s)
{
return string.IsNullOrEmpty(s.Trim()) ? null : s;
}
+
+ ///
+ /// Returns a replacement string if the input string is empty or made of only whitespace characters, otherwise returns the input string
+ ///
+ /// input string
+ /// string to replace with if input string is empty or whitespace
+ /// returns newString if s is null, emtpy, or made of whitespace characters, otherwise returns s
+ public static string ReplaceIfNullOrEmpty(this string s, string newString)
+ {
+ return string.IsNullOrEmpty(s) ? newString : s;
+ }
+
+ ///
+ /// Overload for Contains that allows setting an explicit String Comparison
+ ///
+ /// Source String
+ /// String to check in Source String
+ /// Comparison parameters
+ /// true of string contains "toCheck"
+ public static bool Contains(this string source, string toCheck, StringComparison comp)
+ {
+ if (string.IsNullOrEmpty(source)) return false;
+ return source.IndexOf(toCheck, comp) >= 0;
+ }
+
+ ///
+ /// Performs TrimStart() and TrimEnd() on source string
+ ///
+ /// String to Trim
+ /// Trimmed String
+ public static string TrimAll(this string source)
+ {
+ return string.IsNullOrEmpty(source) ? string.Empty : source.TrimStart().TrimEnd();
+ }
+
+ ///
+ /// Performs TrimStart(chars char[]) and TrimEnd(chars char[]) on source string.
+ ///
+ /// String to Trim
+ /// Char Array to trim from string
+ /// Trimmed String
+ public static string TrimAll(this string source, char[] chars)
+ {
+ return string.IsNullOrEmpty(source) ? string.Empty : source.TrimStart(chars).TrimEnd(chars);
+ }
+
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs
index ebdc87b1..5948de2b 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Factory/DeviceFactory.cs
@@ -172,37 +172,42 @@ namespace PepperDash.Essentials.Core
///
/// Prints the type names and associated metadata from the FactoryMethods collection.
///
- ///
+ ///
public static void GetDeviceFactoryTypes(string filter)
{
- Dictionary types = new Dictionary();
+ var types = !string.IsNullOrEmpty(filter)
+ ? FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value)
+ : FactoryMethods;
- if (!string.IsNullOrEmpty(filter))
- {
- types = FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
- }
- else
- {
- types = FactoryMethods;
- }
-
- Debug.Console(0, "Device Types:");
+ CrestronConsole.ConsoleCommandResponse("Device Types:");
foreach (var type in types.OrderBy(t => t.Key))
{
var description = type.Value.Description;
var cType = "Not Specified by Plugin";
- if(type.Value.CType != null)
+ if (type.Value.CType != null)
{
cType = type.Value.CType.FullName;
}
- Debug.Console(0,
+ CrestronConsole.ConsoleCommandResponse(
@"Type: '{0}'
CType: '{1}'
Description: {2}", type.Key, cType, description);
}
}
+
+ ///
+ /// Returns the device factory dictionary
+ ///
+ ///
+ ///
+ public static Dictionary GetDeviceFactoryDictionary(string filter)
+ {
+ return string.IsNullOrEmpty(filter)
+ ? FactoryMethods
+ : FactoryMethods.Where(k => k.Key.Contains(filter)).ToDictionary(k => k.Key, k => k.Value);
+ }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/File/FileIO.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/File/FileIO.cs
index 51d64230..49b70a0c 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/File/FileIO.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/File/FileIO.cs
@@ -21,35 +21,37 @@ namespace PepperDash.Essentials.Core
///
///
///
- public static FileInfo[] GetFiles(string fileName)
- {
- DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fileName));
- var files = dirInfo.GetFiles(Path.GetFileName(fileName));
- Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fileName);
- if (files.Count() > 0)
- {
- return files;
- }
- else
- {
- return null;
- }
- }
+ public static FileInfo[] GetFiles(string fileName)
+ {
+ string fullFilePath = Global.FilePathPrefix + fileName;
+ DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fullFilePath));
+ var files = dirInfo.GetFiles(Path.GetFileName(fullFilePath));
+ Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fullFilePath);
+ if (files.Count() > 0)
+ {
+ return files;
+ }
+ else
+ {
+ return null;
+ }
+ }
- public static FileInfo GetFile(string fileName)
- {
- DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fileName));
- var files = dirInfo.GetFiles(Path.GetFileName(fileName));
- Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fileName);
- if (files.Count() > 0)
- {
- return files.FirstOrDefault();
- }
- else
- {
- return null;
- }
- }
+ public static FileInfo GetFile(string fileName)
+ {
+ string fullFilePath = Global.FilePathPrefix + fileName;
+ DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fullFilePath));
+ var files = dirInfo.GetFiles(Path.GetFileName(fullFilePath));
+ Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fullFilePath);
+ if (files.Count() > 0)
+ {
+ return files.FirstOrDefault();
+ }
+ else
+ {
+ return null;
+ }
+ }
///
@@ -81,7 +83,7 @@ namespace PepperDash.Essentials.Core
{
if (fileLock.TryEnter())
{
- DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
+ DirectoryInfo dirInfo = new DirectoryInfo(file.DirectoryName);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
@@ -202,7 +204,7 @@ namespace PepperDash.Essentials.Core
public static void WriteDataToFile(string data, string filePath)
{
Thread _WriteFileThread;
- _WriteFileThread = new Thread((O) => _WriteFileMethod(data, filePath), null, Thread.eThreadStartOptions.CreateSuspended);
+ _WriteFileThread = new Thread((O) => _WriteFileMethod(data, Global.FilePathPrefix + "/" + filePath), null, Thread.eThreadStartOptions.CreateSuspended);
_WriteFileThread.Priority = Thread.eThreadPriority.LowestPriority;
_WriteFileThread.Start();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WriteFile Thread");
@@ -217,7 +219,8 @@ namespace PepperDash.Essentials.Core
{
if (fileLock.TryEnter())
{
- using (StreamWriter sw = new StreamWriter(filePath))
+
+ using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(data);
sw.Flush();
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
index 1bf925d6..a675f765 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs
@@ -148,15 +148,20 @@ namespace PepperDash.Essentials.Core.Fusion
ReadGuidFile(guidFilePath);
}
- if (Room.RoomOccupancy != null)
+ var occupancyRoom = Room as IRoomOccupancy;
+
+ if (occupancyRoom != null)
{
- if (Room.OccupancyStatusProviderIsRemote)
+ if (occupancyRoom.RoomOccupancy != null)
{
- SetUpRemoteOccupancy();
- }
- else
- {
- SetUpLocalOccupancy();
+ if (occupancyRoom.OccupancyStatusProviderIsRemote)
+ {
+ SetUpRemoteOccupancy();
+ }
+ else
+ {
+ SetUpLocalOccupancy();
+ }
}
}
@@ -1523,10 +1528,15 @@ namespace PepperDash.Essentials.Core.Fusion
// Tie to method on occupancy object
//occSensorShutdownMinutes.OutputSig.UserObject(new Action(ushort)(b => Room.OccupancyObj.SetShutdownMinutes(b));
+ var occRoom = Room as IRoomOccupancy;
+ if (occRoom != null)
+ {
+ occRoom.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
+ occRoom.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
+ }
RoomOccupancyRemoteStringFeedback = new StringFeedback(() => _roomOccupancyRemoteString);
- Room.RoomOccupancy.RoomIsOccupiedFeedback.LinkInputSig(occSensorAsset.RoomOccupied.InputSig);
- Room.RoomOccupancy.RoomIsOccupiedFeedback.OutputChange += RoomIsOccupiedFeedback_OutputChange;
+
RoomOccupancyRemoteStringFeedback.LinkInputSig(occSensorAsset.RoomOccupancyInfo.InputSig);
//}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs
index 04abc7f8..12df7f14 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/JoinMaps/JoinMapBase.cs
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
-using System.Runtime.InteropServices;
+using System.Text;
using Crestron.SimplSharp.Reflection;
+using Crestron.SimplSharp.CrestronIO;
+using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
@@ -98,22 +101,22 @@ namespace PepperDash.Essentials.Core
///
public void PrintJoinMapInfo()
{
- Debug.Console(0, "{0}:\n", GetType().Name);
+ CrestronConsole.ConsoleCommandResponse("{0}:\n", GetType().Name);
// Get the joins of each type and print them
- Debug.Console(0, "Digitals:");
+ CrestronConsole.ConsoleCommandResponse("Digitals:");
var digitals = Joins.Where(j => (j.Value.JoinType & eJoinType.Digital) == eJoinType.Digital).ToDictionary(j => j.Key, j => j.Value);
- Debug.Console(2, "Found {0} Digital Joins", digitals.Count);
+ CrestronConsole.ConsoleCommandResponse("Found {0} Digital Joins", digitals.Count);
PrintJoinList(GetSortedJoins(digitals));
- Debug.Console(0, "Analogs:");
+ CrestronConsole.ConsoleCommandResponse("Analogs:");
var analogs = Joins.Where(j => (j.Value.JoinType & eJoinType.Analog) == eJoinType.Analog).ToDictionary(j => j.Key, j => j.Value);
- Debug.Console(2, "Found {0} Analog Joins", analogs.Count);
+ CrestronConsole.ConsoleCommandResponse("Found {0} Analog Joins", analogs.Count);
PrintJoinList(GetSortedJoins(analogs));
- Debug.Console(0, "Serials:");
+ CrestronConsole.ConsoleCommandResponse("Serials:");
var serials = Joins.Where(j => (j.Value.JoinType & eJoinType.Serial) == eJoinType.Serial).ToDictionary(j => j.Key, j => j.Value);
- Debug.Console(2, "Found {0} Serial Joins", serials.Count);
+ CrestronConsole.ConsoleCommandResponse("Found {0} Serial Joins", serials.Count);
PrintJoinList(GetSortedJoins(serials));
}
@@ -136,7 +139,7 @@ namespace PepperDash.Essentials.Core
{
foreach (var join in joins)
{
- Debug.Console(0,
+ CrestronConsole.ConsoleCommandResponse(
@"Join Number: {0} | Label: '{1}' | JoinSpan: '{2}' | Type: '{3}' | Capabilities: '{4}'",
join.Value.JoinNumber,
join.Value.Label,
@@ -193,19 +196,6 @@ namespace PepperDash.Essentials.Core
protected void AddJoins(Type type)
{
- // Add all the JoinDataComplete properties to the Joins Dictionary and pass in the offset
- //Joins = this.GetType()
- // .GetCType()
- // .GetFields(BindingFlags.Public | BindingFlags.Instance)
- // .Where(field => field.IsDefined(typeof(JoinNameAttribute), true))
- // .Select(field => (JoinDataComplete)field.GetValue(this))
- // .ToDictionary(join => join.GetNameAttribute(), join =>
- // {
- // join.SetJoinOffset(_joinOffset);
- // return join;
- // });
-
- //type = this.GetType(); <- this wasn't working because 'this' was always the base class, never the derived class
var fields =
type.GetCType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
@@ -219,7 +209,7 @@ namespace PepperDash.Essentials.Core
if (value == null)
{
- Debug.Console(0, "Unable to caset base class to {0}", type.Name);
+ Debug.Console(0, "Unable to cast base class to {0}", type.Name);
continue;
}
@@ -244,23 +234,69 @@ namespace PepperDash.Essentials.Core
///
public void PrintJoinMapInfo()
{
- Debug.Console(0, "{0}:\n", GetType().Name);
+ var sb = JoinmapStringBuilder();
+
+ CrestronConsole.ConsoleCommandResponse(sb.ToString());
+ }
+
+ private StringBuilder JoinmapStringBuilder()
+ {
+ var sb = new StringBuilder();
// Get the joins of each type and print them
- Debug.Console(0, "Digitals:");
- var digitals = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Digital) == eJoinType.Digital).ToDictionary(j => j.Key, j => j.Value);
- Debug.Console(2, "Found {0} Digital Joins", digitals.Count);
- PrintJoinList(GetSortedJoins(digitals));
+ sb.AppendLine(String.Format("# {0}", GetType().Name));
+ sb.AppendLine();
+ sb.AppendLine("## Digitals");
+ sb.AppendLine();
+ // Get the joins of each type and print them
+ var digitals =
+ Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Digital) == eJoinType.Digital)
+ .ToDictionary(j => j.Key, j => j.Value);
+ var digitalSb = AppendJoinList(GetSortedJoins(digitals));
+ digitalSb.AppendLine("## Analogs");
+ digitalSb.AppendLine();
- Debug.Console(0, "Analogs:");
- var analogs = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Analog) == eJoinType.Analog).ToDictionary(j => j.Key, j => j.Value);
- Debug.Console(2, "Found {0} Analog Joins", analogs.Count);
- PrintJoinList(GetSortedJoins(analogs));
-
- Debug.Console(0, "Serials:");
- var serials = Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Serial) == eJoinType.Serial).ToDictionary(j => j.Key, j => j.Value);
- Debug.Console(2, "Found {0} Serial Joins", serials.Count);
- PrintJoinList(GetSortedJoins(serials));
+ var analogs =
+ Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Analog) == eJoinType.Analog)
+ .ToDictionary(j => j.Key, j => j.Value);
+ var analogSb = AppendJoinList(GetSortedJoins(analogs));
+ analogSb.AppendLine("## Serials");
+ analogSb.AppendLine();
+
+ var serials =
+ Joins.Where(j => (j.Value.Metadata.JoinType & eJoinType.Serial) == eJoinType.Serial)
+ .ToDictionary(j => j.Key, j => j.Value);
+ var serialSb = AppendJoinList(GetSortedJoins(serials));
+
+ sb.EnsureCapacity(sb.Length + digitalSb.Length + analogSb.Length + serialSb.Length);
+ sb.Append(digitalSb).Append(analogSb).Append(serialSb);
+ return sb;
+ }
+
+ ///
+ /// Prints the join information to console
+ ///
+ public void MarkdownJoinMapInfo(string deviceKey, string bridgeKey)
+ {
+ var pluginType = GetType().Name;
+
+ CrestronConsole.ConsoleCommandResponse("{0}:\n", pluginType);
+
+
+
+ WriteJoinmapMarkdown(JoinmapStringBuilder(), pluginType, bridgeKey, deviceKey);
+
+ }
+
+ private static void WriteJoinmapMarkdown(StringBuilder stringBuilder, string pluginType, string bridgeKey, string deviceKey)
+ {
+ var fileName = String.Format("{0}{1}{2}__{3}__{4}.md", Global.FilePathPrefix, "joinMaps/", pluginType, bridgeKey, deviceKey);
+
+ using (var sw = new StreamWriter(fileName))
+ {
+ sw.WriteLine(stringBuilder.ToString());
+ CrestronConsole.ConsoleCommandResponse("Joinmap Readme generated and written to {0}", fileName);
+ }
}
@@ -269,7 +305,7 @@ namespace PepperDash.Essentials.Core
///
///
///
- List> GetSortedJoins(Dictionary joins)
+ static List> GetSortedJoins(Dictionary joins)
{
var sortedJoins = joins.ToList();
@@ -278,19 +314,38 @@ namespace PepperDash.Essentials.Core
return sortedJoins;
}
- void PrintJoinList(List> joins)
+
+ static StringBuilder AppendJoinList(List> joins)
{
+ var sb = new StringBuilder();
+ const string stringFormatter = "| {0} | {1} | {2} | {3} | {4} |";
+ const int joinNumberLen = 11;
+ const int joinSpanLen = 9;
+ const int typeLen = 19;
+ const int capabilitiesLen = 12;
+ var descriptionLen = (from @join in joins select @join.Value into j select j.Metadata.Description.Length).Concat(new[] {11}).Max();
+
+ //build header
+ sb.AppendLine(String.Format(stringFormatter,
+ String.Format("Join Number").PadRight(joinNumberLen, ' '),
+ String.Format("Join Span").PadRight(joinSpanLen, ' '),
+ String.Format("Description").PadRight(descriptionLen, ' '),
+ String.Format("Type").PadRight(typeLen, ' '),
+ String.Format("Capabilities").PadRight(capabilitiesLen, ' ')));
+ //build table seperator
+ sb.AppendLine(String.Format(stringFormatter,
+ new String('-', joinNumberLen),
+ new String('-', joinSpanLen),
+ new String('-', descriptionLen),
+ new String('-', typeLen),
+ new String('-', capabilitiesLen)));
+
foreach (var join in joins)
{
- Debug.Console(0,
- @"Join Number: {0} | JoinSpan: '{1}' | JoinName: {2} | Description: '{3}' | Type: '{4}' | Capabilities: '{5}'",
- join.Value.JoinNumber,
- join.Value.JoinSpan,
- join.Key,
- String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName,
- join.Value.Metadata.JoinType.ToString(),
- join.Value.Metadata.JoinCapabilities.ToString());
+ sb.AppendLine(join.Value.GetMarkdownFormattedData(stringFormatter, descriptionLen));
}
+ sb.AppendLine();
+ return sb;
}
///
@@ -301,16 +356,18 @@ namespace PepperDash.Essentials.Core
{
foreach (var customJoinData in joinData)
{
- var join = Joins[customJoinData.Key];
+ JoinDataComplete join;
+
+ if (!Joins.TryGetValue(customJoinData.Key, out join))
+ {
+ Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
+ continue;
+ }
if (join != null)
{
join.SetCustomJoinData(customJoinData.Value);
}
- else
- {
- Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
- }
}
PrintJoinMapInfo();
@@ -459,6 +516,64 @@ namespace PepperDash.Essentials.Core
Metadata = metadata;
}
+ public string GetMarkdownFormattedData(string stringFormatter, int descriptionLen)
+ {
+
+ //Fixed Width Headers
+ var joinNumberLen = String.Format("Join Number").Length;
+ var joinSpanLen = String.Format("Join Span").Length;
+ var typeLen = String.Format("AnalogDigitalSerial").Length;
+ var capabilitiesLen = String.Format("ToFromFusion").Length;
+
+ //Track which one failed, if it did
+ const string placeholder = "unknown";
+ var dataArray = new Dictionary
+ {
+ {"joinNumber", placeholder.PadRight(joinNumberLen, ' ')},
+ {"joinSpan", placeholder.PadRight(joinSpanLen, ' ')},
+ {"description", placeholder.PadRight(descriptionLen, ' ')},
+ {"joinType", placeholder.PadRight(typeLen, ' ')},
+ {"capabilities", placeholder.PadRight(capabilitiesLen, ' ')}
+ };
+
+
+ try
+ {
+ dataArray["joinNumber"] = String.Format("{0}", JoinNumber.ToString(CultureInfo.InvariantCulture).ReplaceIfNullOrEmpty(placeholder)).PadRight(joinNumberLen, ' ');
+ dataArray["joinSpan"] = String.Format("{0}", JoinSpan.ToString(CultureInfo.InvariantCulture).ReplaceIfNullOrEmpty(placeholder)).PadRight(joinSpanLen, ' ');
+ dataArray["description"] = String.Format("{0}", Metadata.Description.ReplaceIfNullOrEmpty(placeholder)).PadRight(descriptionLen, ' ');
+ dataArray["joinType"] = String.Format("{0}", Metadata.JoinType.ToString().ReplaceIfNullOrEmpty(placeholder)).PadRight(typeLen, ' ');
+ dataArray["capabilities"] = String.Format("{0}", Metadata.JoinCapabilities.ToString().ReplaceIfNullOrEmpty(placeholder)).PadRight(capabilitiesLen, ' ');
+
+ return String.Format(stringFormatter,
+ dataArray["joinNumber"],
+ dataArray["joinSpan"],
+ dataArray["description"],
+ dataArray["joinType"],
+ dataArray["capabilities"]);
+
+ }
+ catch (Exception e)
+ {
+ //Don't Throw - we don't want to kill the system if this falls over - it's not mission critical. Print the error, use placeholder data
+ var errorKey = string.Empty;
+ foreach (var item in dataArray)
+ {
+ if (item.Value.TrimEnd() == placeholder) continue;
+ errorKey = item.Key;
+ break;
+ }
+ Debug.Console(0, "Unable to decode join metadata {1}- {0}", e.Message, !String.IsNullOrEmpty(errorKey) ? (' ' + errorKey) : String.Empty);
+ return String.Format(stringFormatter,
+ dataArray["joinNumber"],
+ dataArray["joinSpan"],
+ dataArray["description"],
+ dataArray["joinType"],
+ dataArray["capabilities"]);
+ }
+ }
+
+
///
/// Sets the join offset value
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
index 056686b1..8a7f379a 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Monitoring/SystemMonitorController.cs
@@ -43,7 +43,20 @@ namespace PepperDash.Essentials.Core.Monitoring
public StringFeedback UptimeFeedback { get; set; }
public StringFeedback LastStartFeedback { get; set; }
- public SystemMonitorController(string key)
+ public BoolFeedback IsApplianceFeedback { get; protected set; }
+ private bool _isApplianceFb
+ {
+ get { return CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance; }
+ }
+
+ public BoolFeedback IsServerFeedback { get; protected set; }
+ private bool _isServerFb
+ {
+ get { return CrestronEnvironment.DevicePlatform == eDevicePlatform.Server; }
+ }
+
+
+ public SystemMonitorController(string key)
: base(key)
{
Debug.Console(2, this, "Adding SystemMonitorController.");
@@ -63,6 +76,9 @@ namespace PepperDash.Essentials.Core.Monitoring
UptimeFeedback = new StringFeedback(() => _uptime);
LastStartFeedback = new StringFeedback(()=> _lastStart);
+ IsApplianceFeedback = new BoolFeedback(() => _isApplianceFb);
+ IsServerFeedback = new BoolFeedback(() => _isServerFb);
+
ProgramStatusFeedbackCollection = new Dictionary();
foreach (var prog in SystemMonitor.ProgramCollection)
@@ -123,6 +139,26 @@ namespace PepperDash.Essentials.Core.Monitoring
_uptime = uptimeRaw.Substring(forIndex + 4);
}
+ private static void ProcessorReboot()
+ {
+ if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Server) return;
+
+ var response = string.Empty;
+ CrestronConsole.SendControlSystemCommand("reboot", ref response);
+ }
+
+ private static void ProgramReset(uint index)
+ {
+ if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Server) return;
+
+ if (index <= 0 || index > 10) return;
+
+ var cmd = string.Format("progreset -p:{0}", index);
+
+ var response = string.Empty;
+ CrestronConsole.SendControlSystemCommand(cmd, ref response);
+ }
+
private void CrestronEnvironmentOnEthernetEventHandler(EthernetEventArgs ethernetEventArgs)
{
if (ethernetEventArgs.EthernetEventType != eEthernetEventType.LinkUp) return;
@@ -185,6 +221,9 @@ namespace PepperDash.Essentials.Core.Monitoring
SerialNumberFeedback.FireUpdate();
ModelFeedback.FireUpdate();
+ IsApplianceFeedback.FireUpdate();
+ IsServerFeedback.FireUpdate();
+
OnSystemMonitorPropertiesChanged();
}
@@ -237,6 +276,11 @@ namespace PepperDash.Essentials.Core.Monitoring
UptimeFeedback.LinkInputSig(trilist.StringInput[joinMap.Uptime.JoinNumber]);
LastStartFeedback.LinkInputSig(trilist.StringInput[joinMap.LastBoot.JoinNumber]);
+ trilist.SetSigHeldAction(joinMap.ProcessorReboot.JoinNumber, 10000, ProcessorReboot);
+
+ IsApplianceFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsAppliance.JoinNumber]);
+ IsServerFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsServer.JoinNumber]);
+
// iterate the program status feedback collection and map all the joins
LinkProgramInfoJoins(this, trilist, joinMap);
@@ -301,11 +345,13 @@ namespace PepperDash.Essentials.Core.Monitoring
p.Value.AggregatedProgramInfoFeedback.LinkInputSig(
trilist.StringInput[programSlotJoinStart + joinMap.AggregatedProgramInfo.JoinNumber]);
+ trilist.SetSigHeldAction(programSlotJoinStart + joinMap.ProgramReset.JoinNumber, 10000, () => ProgramReset(programNumber));
+
programSlotJoinStart = programSlotJoinStart + joinMap.ProgramOffsetJoin.JoinSpan;
}
- }
+ }
- //// Sets the time zone
+ //// Sets the time zone
//public void SetTimeZone(int timeZone)
//{
// SystemMonitor.TimeZoneInformation.TimeZoneNumber = timeZone;
@@ -517,11 +563,11 @@ namespace PepperDash.Essentials.Core.Monitoring
ProgramUnregisteredFeedback =
new BoolFeedback(() => Program.RegistrationState == eProgramRegistrationState.Unregister);
ProgramUnregisteredFeedback.FireUpdate();
-
- ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile);
+
+ ProgramNameFeedback = new StringFeedback(() => ProgramInfo.ProgramFile);
+ CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb);
+ EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment);
ProgramCompileTimeFeedback = new StringFeedback(() => ProgramInfo.CompileTime);
- CrestronDataBaseVersionFeedback = new StringFeedback(() => ProgramInfo.CrestronDb);
- EnvironmentVersionFeedback = new StringFeedback(() => ProgramInfo.Environment);
AggregatedProgramInfoFeedback = new StringFeedback(() => JsonConvert.SerializeObject(ProgramInfo));
GetProgramInfo();
@@ -574,9 +620,9 @@ namespace PepperDash.Essentials.Core.Monitoring
// Assume no valid program info. Constructing a new object will wipe all properties
ProgramInfo = new ProgramInfo(Program.Number)
{
- OperatingState = Program.OperatingState,
+ OperatingState = Program.OperatingState,
RegistrationState = Program.RegistrationState
- };
+ };
UpdateFeedbacks();
@@ -593,13 +639,20 @@ namespace PepperDash.Essentials.Core.Monitoring
if (ProgramInfo.ProgramFile.Contains(".dll"))
{
- // SSP Program
+ // SSP Program
ProgramInfo.FriendlyName = ParseConsoleData(response, "Friendly Name", ": ", "\n");
ProgramInfo.ApplicationName = ParseConsoleData(response, "Application Name", ": ", "\n");
ProgramInfo.ProgramTool = ParseConsoleData(response, "Program Tool", ": ", "\n");
ProgramInfo.MinFirmwareVersion = ParseConsoleData(response, "Min Firmware Version", ": ",
"\n");
ProgramInfo.PlugInVersion = ParseConsoleData(response, "PlugInVersion", ": ", "\n");
+
+ ProgramInfo.ProgramFile += string.Format(" {0}.{1}.{2}",
+ ProgramInfo.CompilerRevisionInfo.Major,
+ ProgramInfo.CompilerRevisionInfo.Minor,
+ ProgramInfo.CompilerRevisionInfo.Build);
+
+ ProgramInfo.Environment = ProgramInfo.ProgramTool;
}
else if (ProgramInfo.ProgramFile.Contains(".smw"))
{
@@ -690,6 +743,15 @@ namespace PepperDash.Essentials.Core.Monitoring
[JsonProperty("compilerRevision")]
public string CompilerRevision { get; set; }
+ [JsonIgnore]
+ public Version CompilerRevisionInfo
+ {
+ get
+ {
+ return new Version(CompilerRevision);
+ }
+ }
+
[JsonProperty("compileTime")]
public string CompileTime { get; set; }
@@ -730,7 +792,7 @@ namespace PepperDash.Essentials.Core.Monitoring
ProgramFile = "";
FriendlyName = "";
CompilerRevision = "";
- CompileTime = "";
+ CompileTime = "";
Include4Dat = "";
SystemName = "";
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs
index 16b2f265..73f15cf2 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorController.cs
@@ -85,18 +85,32 @@ namespace PepperDash.Essentials.Core
{
if (_partitionSensor.IsOnline == false) return;
- Debug.Console(1, this, "Attempting to apply settings to sensor from config");
+ // Default to enable
+ _partitionSensor.Enable.BoolValue = true;
- if (PropertiesConfig.Sensitivity != null)
- {
- Debug.Console(1, this, "Sensitivity found, attempting to set value '{0}' from config",
- PropertiesConfig.Sensitivity);
- _partitionSensor.Sensitivity.UShortValue = (ushort) PropertiesConfig.Sensitivity;
- }
- else
- {
- Debug.Console(1, this, "Sensitivity null, no value specified in config");
- }
+ Debug.Console(1, this, "Attempting to apply settings to sensor from config");
+
+ if (PropertiesConfig.Sensitivity != null)
+ {
+ Debug.Console(1, this, "Sensitivity found, attempting to set value '{0}' from config",
+ PropertiesConfig.Sensitivity);
+ _partitionSensor.Sensitivity.UShortValue = (ushort)PropertiesConfig.Sensitivity;
+ }
+ else
+ {
+ Debug.Console(1, this, "Sensitivity null, no value specified in config");
+ }
+
+ if (PropertiesConfig.Enable != null)
+ {
+ Debug.Console(1, this, "Enable found, attempting to set value '{0}' from config",
+ PropertiesConfig.Enable);
+ _partitionSensor.Enable.BoolValue = (bool)PropertiesConfig.Enable;
+ }
+ else
+ {
+ Debug.Console(1, this, "Enable null, no value specified in config");
+ }
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs
index 8a303662..c9f715b5 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PartitionSensor/GlsPartitionSensorPropertiesConfig.cs
@@ -16,6 +16,9 @@ namespace PepperDash_Essentials_Core.PartitionSensor
/// The sensitivity range shall be between 1(lowest) to 10 (highest).
///
[JsonProperty("sensitivity")]
- public ushort? Sensitivity { get; set; }
+ public ushort? Sensitivity { get; set; }
+
+ [JsonProperty("enable")]
+ public bool? Enable { get; set; }
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
index dfa59b88..6b7a3ad9 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj
@@ -83,7 +83,7 @@
..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll
-
+
False
..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll
@@ -92,6 +92,10 @@
..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll
False
+
+ False
+ ..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCWSHelperInterface.dll
+
False
..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll
@@ -123,6 +127,10 @@
+
+
+
+
@@ -177,18 +185,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj.DotSettings b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj.DotSettings
new file mode 100644
index 00000000..cb991a69
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj.DotSettings
@@ -0,0 +1,3 @@
+
+ True
+ False
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs
index 9da843b8..dcc492df 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Plugins/PluginLoader.cs
@@ -194,13 +194,13 @@ namespace PepperDash.Essentials
///
public static void ReportAssemblyVersions(string command)
{
- Debug.Console(0, "Loaded Assemblies:");
+
+ CrestronConsole.ConsoleCommandResponse("Loaded Assemblies:" + CrestronEnvironment.NewLine);
foreach (var assembly in LoadedAssemblies)
{
- Debug.Console(0, "{0} Version: {1}", assembly.Name, assembly.Version);
+ CrestronConsole.ConsoleCommandResponse("{0} Version: {1}" + CrestronEnvironment.NewLine, assembly.Name, assembly.Version);
}
}
-
///
/// Moves any .dll assemblies not already loaded from the plugins folder to loadedPlugins folder
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs
index 9080435e..d4fe1af3 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Queues/GenericQueue.cs
@@ -1,5 +1,6 @@
using System;
using Crestron.SimplSharp;
+using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharpPro.CrestronThread;
using PepperDash.Core;
@@ -187,9 +188,20 @@ namespace PepperDash.Essentials.Core.Queues
if (_delayEnabled)
Thread.Sleep(_delayTime);
}
+ catch (System.Threading.ThreadAbortException)
+ {
+ //swallowing this exception, as it should only happen on shut down
+ }
catch (Exception ex)
{
- Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue: {1}:{0}", ex.Message, ex);
+ Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
+
+ if (ex.InnerException != null)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "---\r\n{0}", ex.InnerException.Message);
+ Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.InnerException.StackTrace);
+ }
}
}
else _waitHandle.Wait();
@@ -202,7 +214,7 @@ namespace PepperDash.Essentials.Core.Queues
{
if (Disposed)
{
- Debug.Console(1, this, "I've been disposed so you can't enqueue any messages. Are you trying to dispatch a message while the program is stopping?");
+ Debug.Console(1, this, "Queue has been disposed. Enqueuing messages not allowed while program is stopping.");
return;
}
@@ -446,7 +458,14 @@ namespace PepperDash_Essentials_Core.Queues
}
catch (Exception ex)
{
- Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}\r{1}\r{2}", ex.Message, ex.InnerException, ex.StackTrace);
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}", ex.Message);
+ Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
+
+ if (ex.InnerException != null)
+ {
+ Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Caught an exception in the Queue {0}", ex.InnerException.Message);
+ Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.InnerException.StackTrace);
+ }
}
}
else _waitHandle.Wait();
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs
index 81cbff9e..b7440213 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Behaviours/RoomOnToDefaultSourceWhenOccupied.cs
@@ -38,7 +38,7 @@ namespace PepperDash.Essentials.Core
ScheduledEventGroup FeatureEventGroup;
- public IEssentialsRoom Room { get; private set; }
+ public IRoomOccupancy Room { get; private set; }
private Fusion.EssentialsHuddleSpaceFusionSystemControllerBase FusionRoom;
@@ -84,7 +84,7 @@ namespace PepperDash.Essentials.Core
///
void SetUpDevice()
{
- Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as IEssentialsRoom;
+ Room = DeviceManager.GetDeviceForKey(PropertiesConfig.RoomKey) as IRoomOccupancy;
if (Room != null)
{
@@ -235,12 +235,23 @@ namespace PepperDash.Essentials.Core
if (FeatureEnabled)
{
- // Check room power state first
- if (!Room.OnFeedback.BoolValue)
- {
- Debug.Console(1, this, "Powering Room on to default source");
- Room.RunDefaultPresentRoute();
+ var essentialsRoom = Room as IEssentialsRoom;
+
+ if (essentialsRoom != null) {
+ if (!essentialsRoom.OnFeedback.BoolValue)
+ {
+ Debug.Console(1, this, "Powering Room on to default source");
+
+ var defaultRouteRoom = Room as IRunDefaultPresentRoute;
+
+ if (defaultRouteRoom != null)
+ {
+ defaultRouteRoom.RunDefaultPresentRoute();
+ }
+ }
}
+ // Check room power state first
+
}
}
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs
index 352cbfcd..0c7e0de0 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/EssentialsRoomBase.cs
@@ -35,7 +35,7 @@ namespace PepperDash.Essentials.Core
public BoolFeedback IsWarmingUpFeedback { get; private set; }
public BoolFeedback IsCoolingDownFeedback { get; private set; }
- public IOccupancyStatusProvider RoomOccupancy { get; private set; }
+ public IOccupancyStatusProvider RoomOccupancy { get; protected set; }
public bool OccupancyStatusProviderIsRemote { get; private set; }
@@ -343,7 +343,7 @@ namespace PepperDash.Essentials.Core
void RoomIsOccupiedFeedback_OutputChange(object sender, EventArgs e)
{
- if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false)
+ if (RoomOccupancy.RoomIsOccupiedFeedback.BoolValue == false && AllowVacancyTimerToStart())
{
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Notice: Vacancy Detected");
// Trigger the timer when the room is vacant
@@ -362,6 +362,15 @@ namespace PepperDash.Essentials.Core
///
///
public abstract void RoomVacatedForTimeoutPeriod(object o);
+
+ ///
+ /// Allow the vacancy event from an occupancy sensor to turn the room off.
+ ///
+ /// If the timer should be allowed. Defaults to true
+ protected virtual bool AllowVacancyTimerToStart()
+ {
+ return true;
+ }
}
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs
index 2273690f..9a70f980 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/IEssentialsRoom.cs
@@ -17,15 +17,10 @@ namespace PepperDash.Essentials.Core
///
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute, IEnvironmentalControls
{
- BoolFeedback OnFeedback { get; }
-
- event EventHandler RoomOccupancyIsSet;
+ BoolFeedback OnFeedback { get; }
BoolFeedback IsWarmingUpFeedback { get; }
- BoolFeedback IsCoolingDownFeedback { get; }
-
- IOccupancyStatusProvider RoomOccupancy { get; }
- bool OccupancyStatusProviderIsRemote { get; }
+ BoolFeedback IsCoolingDownFeedback { get; }
bool IsMobileControlEnabled { get; }
IMobileControlRoomBridge MobileControlRoomBridge { get; }
@@ -35,31 +30,16 @@ namespace PepperDash.Essentials.Core
SecondsCountdownTimer ShutdownPromptTimer { get; }
int ShutdownPromptSeconds { get; }
int ShutdownVacancySeconds { get; }
- eShutdownType ShutdownType { get; }
-
- EssentialsRoomEmergencyBase Emergency { get; }
-
- Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; }
+ eShutdownType ShutdownType { get; }
string LogoUrlLightBkgnd { get; }
string LogoUrlDarkBkgnd { get; }
- eVacancyMode VacancyMode { get; }
+ void StartShutdown(eShutdownType type);
- bool ZeroVolumeWhenSwtichingVolumeDevices { get; }
+ void Shutdown();
- void StartShutdown(eShutdownType type);
- void StartRoomVacancyTimer(eVacancyMode mode);
-
- void Shutdown();
-
- void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes);
-
- void PowerOnToDefaultOrLastSource();
-
- void SetDefaultLevels();
-
- void RoomVacatedForTimeoutPeriod(object o);
+ void PowerOnToDefaultOrLastSource();
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
index b5121e9c..e962e604 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Room/Interfaces.cs
@@ -41,7 +41,6 @@ namespace PepperDash.Essentials.Core
void RunRouteAction(string routeKey, string sourceListKey);
void RunRouteAction(string routeKey, string sourceListKey, Action successCallback);
-
}
///
@@ -78,4 +77,30 @@ namespace PepperDash.Essentials.Core
bool HasEnvironmentalControlDevices { get; }
}
+ public interface IRoomOccupancy:IKeyed
+ {
+ IOccupancyStatusProvider RoomOccupancy { get; }
+ bool OccupancyStatusProviderIsRemote { get; }
+
+ void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes);
+
+ void RoomVacatedForTimeoutPeriod(object o);
+
+ void StartRoomVacancyTimer(eVacancyMode mode);
+
+ eVacancyMode VacancyMode { get; }
+
+ event EventHandler RoomOccupancyIsSet;
+ }
+
+ public interface IEmergency
+ {
+ EssentialsRoomEmergencyBase Emergency { get; }
+ }
+
+ public interface IMicrophonePrivacy
+ {
+ Core.Privacy.MicrophonePrivacyController MicrophonePrivacy { get; }
+ }
+
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs
index d371c2d6..4cd0d4ff 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/IRoutingInputsExtensions.cs
@@ -1,425 +1,425 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DM;
-
-using PepperDash.Core;
-
-
-namespace PepperDash.Essentials.Core
-{
- public class RouteRequest
- {
- public IRoutingSink Destination {get; set;}
- public IRoutingOutputs Source {get; set;}
- public eRoutingSignalType SignalType {get; set;}
-
- public void HandleCooldown(object sender, FeedbackEventArgs args)
- {
- var coolingDevice = sender as IWarmingCooling;
-
- if(args.BoolValue == false)
- {
- Destination.ReleaseAndMakeRoute(Source, SignalType);
-
- if(sender == null) return;
-
- coolingDevice.IsCoolingDownFeedback.OutputChange -= HandleCooldown;
- }
- }
- }
-
- ///
- /// Extensions added to any IRoutingInputs classes to provide discovery-based routing
- /// on those destinations.
- ///
- public static class IRoutingInputsExtensions
- {
- private static Dictionary RouteRequests = new Dictionary();
- ///
- /// Gets any existing RouteDescriptor for a destination, clears it using ReleaseRoute
- /// and then attempts a new Route and if sucessful, stores that RouteDescriptor
- /// in RouteDescriptorCollection.DefaultCollection
- ///
- public static void ReleaseAndMakeRoute(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
- {
- var routeRequest = new RouteRequest {
- Destination = destination,
- Source = source,
- SignalType = signalType
- };
-
- var coolingDevice = destination as IWarmingCooling;
-
- RouteRequest existingRouteRequest;
-
- //We already have a route request for this device, and it's a cooling device and is cooling
- if (RouteRequests.TryGetValue(destination.Key, out existingRouteRequest) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
- {
- coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRouteRequest.HandleCooldown;
-
- coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
-
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DM;
+
+using PepperDash.Core;
+
+
+namespace PepperDash.Essentials.Core
+{
+ public class RouteRequest
+ {
+ public IRoutingSink Destination {get; set;}
+ public IRoutingOutputs Source {get; set;}
+ public eRoutingSignalType SignalType {get; set;}
+
+ public void HandleCooldown(object sender, FeedbackEventArgs args)
+ {
+ var coolingDevice = sender as IWarmingCooling;
+
+ if(args.BoolValue == false)
+ {
+ Destination.ReleaseAndMakeRoute(Source, SignalType);
+
+ if(sender == null) return;
+
+ coolingDevice.IsCoolingDownFeedback.OutputChange -= HandleCooldown;
+ }
+ }
+ }
+
+ ///
+ /// Extensions added to any IRoutingInputs classes to provide discovery-based routing
+ /// on those destinations.
+ ///
+ public static class IRoutingInputsExtensions
+ {
+ private static Dictionary RouteRequests = new Dictionary();
+ ///
+ /// Gets any existing RouteDescriptor for a destination, clears it using ReleaseRoute
+ /// and then attempts a new Route and if sucessful, stores that RouteDescriptor
+ /// in RouteDescriptorCollection.DefaultCollection
+ ///
+ public static void ReleaseAndMakeRoute(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
+ {
+ var routeRequest = new RouteRequest {
+ Destination = destination,
+ Source = source,
+ SignalType = signalType
+ };
+
+ var coolingDevice = destination as IWarmingCooling;
+
+ RouteRequest existingRouteRequest;
+
+ //We already have a route request for this device, and it's a cooling device and is cooling
+ if (RouteRequests.TryGetValue(destination.Key, out existingRouteRequest) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
+ {
+ coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRouteRequest.HandleCooldown;
+
+ coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
+
RouteRequests[destination.Key] = routeRequest;
- Debug.Console(2, "******************************************************** Device: {0} is cooling down and already has a routing request stored. Storing new route request to route to source key: {1}", destination.Key, routeRequest.Source.Key);
-
- return;
- }
-
- //New Request
- if (coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
- {
- coolingDevice.IsCoolingDownFeedback.OutputChange -= routeRequest.HandleCooldown;
-
- coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
-
+ Debug.Console(2, "******************************************************** Device: {0} is cooling down and already has a routing request stored. Storing new route request to route to source key: {1}", destination.Key, routeRequest.Source.Key);
+
+ return;
+ }
+
+ //New Request
+ if (coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == true)
+ {
+ coolingDevice.IsCoolingDownFeedback.OutputChange -= routeRequest.HandleCooldown;
+
+ coolingDevice.IsCoolingDownFeedback.OutputChange += routeRequest.HandleCooldown;
+
RouteRequests.Add(destination.Key, routeRequest);
Debug.Console(2, "******************************************************** Device: {0} is cooling down. Storing route request to route to source key: {1}", destination.Key, routeRequest.Source.Key);
- return;
- }
-
- if (RouteRequests.ContainsKey(destination.Key) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == false)
- {
+ return;
+ }
+
+ if (RouteRequests.ContainsKey(destination.Key) && coolingDevice != null && coolingDevice.IsCoolingDownFeedback.BoolValue == false)
+ {
RouteRequests.Remove(destination.Key);
Debug.Console(2, "******************************************************** Device: {0} is NOT cooling down. Removing stored route request and routing to source key: {1}", destination.Key, routeRequest.Source.Key);
- }
-
- destination.ReleaseRoute();
-
- RunRouteRequest(routeRequest);
- }
-
- public static void RunRouteRequest(RouteRequest request)
- {
- if (request.Source == null) return;
- var newRoute = request.Destination.GetRouteToSource(request.Source, request.SignalType);
- if (newRoute == null) return;
- RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute);
- Debug.Console(2, request.Destination, "Executing full route");
- newRoute.ExecuteRoutes();
- }
-
- ///
- /// Will release the existing route on the destination, if it is found in
- /// RouteDescriptorCollection.DefaultCollection
- ///
- ///
- public static void ReleaseRoute(this IRoutingSink destination)
- {
- RouteRequest existingRequest;
-
- if (RouteRequests.TryGetValue(destination.Key, out existingRequest) && destination is IWarmingCooling)
- {
- var coolingDevice = destination as IWarmingCooling;
-
- coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRequest.HandleCooldown;
- }
-
- RouteRequests.Remove(destination.Key);
-
- var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination);
- if (current != null)
- {
- Debug.Console(1, destination, "Releasing current route: {0}", current.Source.Key);
- current.ReleaseRoutes();
- }
- }
-
- ///
- /// Builds a RouteDescriptor that contains the steps necessary to make a route between devices.
- /// Routes of type AudioVideo will be built as two separate routes, audio and video. If
- /// a route is discovered, a new RouteDescriptor is returned. If one or both parts
- /// of an audio/video route are discovered a route descriptor is returned. If no route is
- /// discovered, then null is returned
- ///
- public static RouteDescriptor GetRouteToSource(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
- {
- var routeDescr = new RouteDescriptor(source, destination, signalType);
- // if it's a single signal type, find the route
- if ((signalType & (eRoutingSignalType.Audio & eRoutingSignalType.Video)) == (eRoutingSignalType.Audio & eRoutingSignalType.Video))
- {
- Debug.Console(1, destination, "Attempting to build source route from {0}", source.Key);
- if (!destination.GetRouteToSource(source, null, null, signalType, 0, routeDescr))
- routeDescr = null;
- }
- // otherwise, audioVideo needs to be handled as two steps.
- else
- {
- Debug.Console(1, destination, "Attempting to build audio and video routes from {0}", source.Key);
- var audioSuccess = destination.GetRouteToSource(source, null, null, eRoutingSignalType.Audio, 0, routeDescr);
- if (!audioSuccess)
- Debug.Console(1, destination, "Cannot find audio route to {0}", source.Key);
- var videoSuccess = destination.GetRouteToSource(source, null, null, eRoutingSignalType.Video, 0, routeDescr);
- if (!videoSuccess)
- Debug.Console(1, destination, "Cannot find video route to {0}", source.Key);
- if (!audioSuccess && !videoSuccess)
- routeDescr = null;
- }
-
- //Debug.Console(1, destination, "Route{0} discovered", routeDescr == null ? " NOT" : "");
- return routeDescr;
- }
-
- ///
- /// The recursive part of this. Will stop on each device, search its inputs for the
- /// desired source and if not found, invoke this function for the each input port
- /// hoping to find the source.
- ///
- ///
- ///
- /// The RoutingOutputPort whose link is being checked for a route
- /// Prevents Devices from being twice-checked
- /// This recursive function should not be called with AudioVideo
- /// Just an informational counter
- /// The RouteDescriptor being populated as the route is discovered
- /// true if source is hit
- static bool GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source,
- RoutingOutputPort outputPortToUse, List alreadyCheckedDevices,
- eRoutingSignalType signalType, int cycle, RouteDescriptor routeTable)
- {
- cycle++;
- Debug.Console(2, "GetRouteToSource: {0} {1}--> {2}", cycle, source.Key, destination.Key);
-
- RoutingInputPort goodInputPort = null;
- var destDevInputTies = TieLineCollection.Default.Where(t =>
- t.DestinationPort.ParentDevice == destination && (t.Type == signalType || (t.Type & (eRoutingSignalType.Audio | eRoutingSignalType.Video)) == (eRoutingSignalType.Audio | eRoutingSignalType.Video)));
-
- // find a direct tie
- var directTie = destDevInputTies.FirstOrDefault(
- t => t.DestinationPort.ParentDevice == destination
- && t.SourcePort.ParentDevice == source);
- if (directTie != null) // Found a tie directly to the source
- {
- goodInputPort = directTie.DestinationPort;
- }
- else // no direct-connect. Walk back devices.
- {
- Debug.Console(2, destination, "is not directly connected to {0}. Walking down tie lines", source.Key);
-
- // No direct tie? Run back out on the inputs' attached devices...
- // Only the ones that are routing devices
- var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
-
- //Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
- if (alreadyCheckedDevices == null)
- alreadyCheckedDevices = new List();
- alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
-
- foreach (var inputTieToTry in attachedMidpoints)
- {
- var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
- var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
- Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key);
-
- // Check if this previous device has already been walked
- if (alreadyCheckedDevices.Contains(upstreamRoutingDevice))
- {
- Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key);
- continue;
- }
- // haven't seen this device yet. Do it. Pass the output port to the next
- // level to enable switching on success
- var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
- alreadyCheckedDevices, signalType, cycle, routeTable);
- if (upstreamRoutingSuccess)
- {
- Debug.Console(2, destination, "Upstream device route found");
- goodInputPort = inputTieToTry.DestinationPort;
- break; // Stop looping the inputs in this cycle
- }
- }
- }
-
- // we have a route on corresponding inputPort. *** Do the route ***
- if (goodInputPort != null)
- {
- //Debug.Console(2, destination, "adding RouteDescriptor");
- if (outputPortToUse == null)
- {
- // it's a sink device
- routeTable.Routes.Add(new RouteSwitchDescriptor(goodInputPort));
- }
- else if (destination is IRouting)
- {
- routeTable.Routes.Add(new RouteSwitchDescriptor (outputPortToUse, goodInputPort));
- }
- else // device is merely IRoutingInputOutputs
- Debug.Console(2, destination, " No routing. Passthrough device");
- //Debug.Console(2, destination, "Exiting cycle {0}", cycle);
- return true;
- }
-
- Debug.Console(2, destination, "No route found to {0}", source.Key);
- return false;
- }
- }
-
-
-
-
-
- // MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE
-
-
- ///
- /// A collection of RouteDescriptors - typically the static DefaultCollection is used
- ///
- public class RouteDescriptorCollection
- {
- public static RouteDescriptorCollection DefaultCollection
- {
- get
- {
- if (_DefaultCollection == null)
- _DefaultCollection = new RouteDescriptorCollection();
- return _DefaultCollection;
- }
- }
- static RouteDescriptorCollection _DefaultCollection;
-
- List RouteDescriptors = new List();
-
- ///
- /// Adds a RouteDescriptor to the list. If an existing RouteDescriptor for the
- /// destination exists already, it will not be added - in order to preserve
- /// proper route releasing.
- ///
- ///
- public void AddRouteDescriptor(RouteDescriptor descriptor)
- {
- if (RouteDescriptors.Any(t => t.Destination == descriptor.Destination))
- {
- Debug.Console(1, descriptor.Destination,
- "Route to [{0}] already exists in global routes table", descriptor.Source.Key);
- return;
- }
- RouteDescriptors.Add(descriptor);
- }
-
- ///
- /// Gets the RouteDescriptor for a destination
- ///
- /// null if no RouteDescriptor for a destination exists
- public RouteDescriptor GetRouteDescriptorForDestination(IRoutingInputs destination)
- {
- return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination);
- }
-
- ///
- /// Returns the RouteDescriptor for a given destination AND removes it from collection.
- /// Returns null if no route with the provided destination exists.
- ///
- public RouteDescriptor RemoveRouteDescriptor(IRoutingInputs destination)
- {
- var descr = GetRouteDescriptorForDestination(destination);
- if (descr != null)
- RouteDescriptors.Remove(descr);
- return descr;
- }
- }
-
- ///
- /// Represents an collection of individual route steps between Source and Destination
- ///
- public class RouteDescriptor
- {
- public IRoutingInputs Destination { get; private set; }
- public IRoutingOutputs Source { get; private set; }
- public eRoutingSignalType SignalType { get; private set; }
- public List Routes { get; private set; }
-
-
- public RouteDescriptor(IRoutingOutputs source, IRoutingInputs destination, eRoutingSignalType signalType)
- {
- Destination = destination;
- Source = source;
- SignalType = signalType;
- Routes = new List();
- }
-
- ///
- /// Executes all routes described in this collection. Typically called via
- /// extension method IRoutingInputs.ReleaseAndMakeRoute()
- ///
- public void ExecuteRoutes()
- {
- foreach (var route in Routes)
- {
- Debug.Console(2, "ExecuteRoutes: {0}", route.ToString());
- if (route.SwitchingDevice is IRoutingSink)
- {
- var device = route.SwitchingDevice as IRoutingSinkWithSwitching;
- if (device == null)
- continue;
-
- device.ExecuteSwitch(route.InputPort.Selector);
- }
- else if (route.SwitchingDevice is IRouting)
- {
- (route.SwitchingDevice as IRouting).ExecuteSwitch(route.InputPort.Selector, route.OutputPort.Selector, SignalType);
- route.OutputPort.InUseTracker.AddUser(Destination, "destination-" + SignalType);
- Debug.Console(2, "Output port {0} routing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
- }
- }
- }
-
- ///
- /// Releases all routes in this collection. Typically called via
- /// extension method IRoutingInputs.ReleaseAndMakeRoute()
- ///
- public void ReleaseRoutes()
- {
- foreach (var route in Routes)
- {
- if (route.SwitchingDevice is IRouting)
- {
- // Pull the route from the port. Whatever is watching the output's in use tracker is
- // responsible for responding appropriately.
- route.OutputPort.InUseTracker.RemoveUser(Destination, "destination-" + SignalType);
- Debug.Console(2, "Port {0} releasing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
- }
- }
- }
-
- public override string ToString()
- {
- var routesText = Routes.Select(r => r.ToString()).ToArray();
- return string.Format("Route table from {0} to {1}:\r{2}", Source.Key, Destination.Key, string.Join("\r", routesText));
- }
- }
-
- ///
- /// Represents an individual link for a route
- ///
- public class RouteSwitchDescriptor
- {
- public IRoutingInputs SwitchingDevice { get { return InputPort.ParentDevice; } }
- public RoutingOutputPort OutputPort { get; set; }
- public RoutingInputPort InputPort { get; set; }
-
- public RouteSwitchDescriptor(RoutingInputPort inputPort)
- {
- InputPort = inputPort;
- }
-
- public RouteSwitchDescriptor(RoutingOutputPort outputPort, RoutingInputPort inputPort)
- {
- InputPort = inputPort;
- OutputPort = outputPort;
- }
-
- public override string ToString()
- {
- if(SwitchingDevice is IRouting)
- return string.Format("{0} switches output '{1}' to input '{2}'", SwitchingDevice.Key, OutputPort.Selector, InputPort.Selector);
- else
- return string.Format("{0} switches to input '{1}'", SwitchingDevice.Key, InputPort.Selector);
-
- }
- }
+ }
+
+ destination.ReleaseRoute();
+
+ RunRouteRequest(routeRequest);
+ }
+
+ public static void RunRouteRequest(RouteRequest request)
+ {
+ if (request.Source == null) return;
+ var newRoute = request.Destination.GetRouteToSource(request.Source, request.SignalType);
+ if (newRoute == null) return;
+ RouteDescriptorCollection.DefaultCollection.AddRouteDescriptor(newRoute);
+ Debug.Console(2, request.Destination, "Executing full route");
+ newRoute.ExecuteRoutes();
+ }
+
+ ///
+ /// Will release the existing route on the destination, if it is found in
+ /// RouteDescriptorCollection.DefaultCollection
+ ///
+ ///
+ public static void ReleaseRoute(this IRoutingSink destination)
+ {
+ RouteRequest existingRequest;
+
+ if (RouteRequests.TryGetValue(destination.Key, out existingRequest) && destination is IWarmingCooling)
+ {
+ var coolingDevice = destination as IWarmingCooling;
+
+ coolingDevice.IsCoolingDownFeedback.OutputChange -= existingRequest.HandleCooldown;
+ }
+
+ RouteRequests.Remove(destination.Key);
+
+ var current = RouteDescriptorCollection.DefaultCollection.RemoveRouteDescriptor(destination);
+ if (current != null)
+ {
+ Debug.Console(1, destination, "Releasing current route: {0}", current.Source.Key);
+ current.ReleaseRoutes();
+ }
+ }
+
+ ///
+ /// Builds a RouteDescriptor that contains the steps necessary to make a route between devices.
+ /// Routes of type AudioVideo will be built as two separate routes, audio and video. If
+ /// a route is discovered, a new RouteDescriptor is returned. If one or both parts
+ /// of an audio/video route are discovered a route descriptor is returned. If no route is
+ /// discovered, then null is returned
+ ///
+ public static RouteDescriptor GetRouteToSource(this IRoutingSink destination, IRoutingOutputs source, eRoutingSignalType signalType)
+ {
+ var routeDescr = new RouteDescriptor(source, destination, signalType);
+ // if it's a single signal type, find the route
+ if ((signalType & (eRoutingSignalType.Audio & eRoutingSignalType.Video)) == (eRoutingSignalType.Audio & eRoutingSignalType.Video))
+ {
+ Debug.Console(1, destination, "Attempting to build source route from {0}", source.Key);
+ if (!destination.GetRouteToSource(source, null, null, signalType, 0, routeDescr))
+ routeDescr = null;
+ }
+ // otherwise, audioVideo needs to be handled as two steps.
+ else
+ {
+ Debug.Console(1, destination, "Attempting to build audio and video routes from {0}", source.Key);
+ var audioSuccess = destination.GetRouteToSource(source, null, null, eRoutingSignalType.Audio, 0, routeDescr);
+ if (!audioSuccess)
+ Debug.Console(1, destination, "Cannot find audio route to {0}", source.Key);
+ var videoSuccess = destination.GetRouteToSource(source, null, null, eRoutingSignalType.Video, 0, routeDescr);
+ if (!videoSuccess)
+ Debug.Console(1, destination, "Cannot find video route to {0}", source.Key);
+ if (!audioSuccess && !videoSuccess)
+ routeDescr = null;
+ }
+
+ //Debug.Console(1, destination, "Route{0} discovered", routeDescr == null ? " NOT" : "");
+ return routeDescr;
+ }
+
+ ///
+ /// The recursive part of this. Will stop on each device, search its inputs for the
+ /// desired source and if not found, invoke this function for the each input port
+ /// hoping to find the source.
+ ///
+ ///
+ ///
+ /// The RoutingOutputPort whose link is being checked for a route
+ /// Prevents Devices from being twice-checked
+ /// This recursive function should not be called with AudioVideo
+ /// Just an informational counter
+ /// The RouteDescriptor being populated as the route is discovered
+ /// true if source is hit
+ static bool GetRouteToSource(this IRoutingInputs destination, IRoutingOutputs source,
+ RoutingOutputPort outputPortToUse, List alreadyCheckedDevices,
+ eRoutingSignalType signalType, int cycle, RouteDescriptor routeTable)
+ {
+ cycle++;
+ Debug.Console(2, "GetRouteToSource: {0} {1}--> {2}", cycle, source.Key, destination.Key);
+
+ RoutingInputPort goodInputPort = null;
+ var destDevInputTies = TieLineCollection.Default.Where(t =>
+ t.DestinationPort.ParentDevice == destination && (t.Type == signalType || (t.Type & (eRoutingSignalType.Audio | eRoutingSignalType.Video)) == (eRoutingSignalType.Audio | eRoutingSignalType.Video)));
+
+ // find a direct tie
+ var directTie = destDevInputTies.FirstOrDefault(
+ t => t.DestinationPort.ParentDevice == destination
+ && t.SourcePort.ParentDevice == source);
+ if (directTie != null) // Found a tie directly to the source
+ {
+ goodInputPort = directTie.DestinationPort;
+ }
+ else // no direct-connect. Walk back devices.
+ {
+ Debug.Console(2, destination, "is not directly connected to {0}. Walking down tie lines", source.Key);
+
+ // No direct tie? Run back out on the inputs' attached devices...
+ // Only the ones that are routing devices
+ var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
+
+ //Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
+ if (alreadyCheckedDevices == null)
+ alreadyCheckedDevices = new List();
+ alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
+
+ foreach (var inputTieToTry in attachedMidpoints)
+ {
+ var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
+ var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
+ Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key);
+
+ // Check if this previous device has already been walked
+ if (alreadyCheckedDevices.Contains(upstreamRoutingDevice))
+ {
+ Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key);
+ continue;
+ }
+ // haven't seen this device yet. Do it. Pass the output port to the next
+ // level to enable switching on success
+ var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
+ alreadyCheckedDevices, signalType, cycle, routeTable);
+ if (upstreamRoutingSuccess)
+ {
+ Debug.Console(2, destination, "Upstream device route found");
+ goodInputPort = inputTieToTry.DestinationPort;
+ break; // Stop looping the inputs in this cycle
+ }
+ }
+ }
+
+ // we have a route on corresponding inputPort. *** Do the route ***
+ if (goodInputPort != null)
+ {
+ //Debug.Console(2, destination, "adding RouteDescriptor");
+ if (outputPortToUse == null)
+ {
+ // it's a sink device
+ routeTable.Routes.Add(new RouteSwitchDescriptor(goodInputPort));
+ }
+ else if (destination is IRouting)
+ {
+ routeTable.Routes.Add(new RouteSwitchDescriptor (outputPortToUse, goodInputPort));
+ }
+ else // device is merely IRoutingInputOutputs
+ Debug.Console(2, destination, " No routing. Passthrough device");
+ //Debug.Console(2, destination, "Exiting cycle {0}", cycle);
+ return true;
+ }
+
+ Debug.Console(2, destination, "No route found to {0}", source.Key);
+ return false;
+ }
+ }
+
+
+
+
+
+ // MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE
+
+
+ ///
+ /// A collection of RouteDescriptors - typically the static DefaultCollection is used
+ ///
+ public class RouteDescriptorCollection
+ {
+ public static RouteDescriptorCollection DefaultCollection
+ {
+ get
+ {
+ if (_DefaultCollection == null)
+ _DefaultCollection = new RouteDescriptorCollection();
+ return _DefaultCollection;
+ }
+ }
+ static RouteDescriptorCollection _DefaultCollection;
+
+ List RouteDescriptors = new List();
+
+ ///
+ /// Adds a RouteDescriptor to the list. If an existing RouteDescriptor for the
+ /// destination exists already, it will not be added - in order to preserve
+ /// proper route releasing.
+ ///
+ ///
+ public void AddRouteDescriptor(RouteDescriptor descriptor)
+ {
+ if (RouteDescriptors.Any(t => t.Destination == descriptor.Destination))
+ {
+ Debug.Console(1, descriptor.Destination,
+ "Route to [{0}] already exists in global routes table", descriptor.Source.Key);
+ return;
+ }
+ RouteDescriptors.Add(descriptor);
+ }
+
+ ///
+ /// Gets the RouteDescriptor for a destination
+ ///
+ /// null if no RouteDescriptor for a destination exists
+ public RouteDescriptor GetRouteDescriptorForDestination(IRoutingInputs destination)
+ {
+ return RouteDescriptors.FirstOrDefault(rd => rd.Destination == destination);
+ }
+
+ ///
+ /// Returns the RouteDescriptor for a given destination AND removes it from collection.
+ /// Returns null if no route with the provided destination exists.
+ ///
+ public RouteDescriptor RemoveRouteDescriptor(IRoutingInputs destination)
+ {
+ var descr = GetRouteDescriptorForDestination(destination);
+ if (descr != null)
+ RouteDescriptors.Remove(descr);
+ return descr;
+ }
+ }
+
+ ///
+ /// Represents an collection of individual route steps between Source and Destination
+ ///
+ public class RouteDescriptor
+ {
+ public IRoutingInputs Destination { get; private set; }
+ public IRoutingOutputs Source { get; private set; }
+ public eRoutingSignalType SignalType { get; private set; }
+ public List Routes { get; private set; }
+
+
+ public RouteDescriptor(IRoutingOutputs source, IRoutingInputs destination, eRoutingSignalType signalType)
+ {
+ Destination = destination;
+ Source = source;
+ SignalType = signalType;
+ Routes = new List();
+ }
+
+ ///
+ /// Executes all routes described in this collection. Typically called via
+ /// extension method IRoutingInputs.ReleaseAndMakeRoute()
+ ///
+ public void ExecuteRoutes()
+ {
+ foreach (var route in Routes)
+ {
+ Debug.Console(2, "ExecuteRoutes: {0}", route.ToString());
+ if (route.SwitchingDevice is IRoutingSink)
+ {
+ var device = route.SwitchingDevice as IRoutingSinkWithSwitching;
+ if (device == null)
+ continue;
+
+ device.ExecuteSwitch(route.InputPort.Selector);
+ }
+ else if (route.SwitchingDevice is IRouting)
+ {
+ (route.SwitchingDevice as IRouting).ExecuteSwitch(route.InputPort.Selector, route.OutputPort.Selector, SignalType);
+ route.OutputPort.InUseTracker.AddUser(Destination, "destination-" + SignalType);
+ Debug.Console(2, "Output port {0} routing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
+ }
+ }
+ }
+
+ ///
+ /// Releases all routes in this collection. Typically called via
+ /// extension method IRoutingInputs.ReleaseAndMakeRoute()
+ ///
+ public void ReleaseRoutes()
+ {
+ foreach (var route in Routes)
+ {
+ if (route.SwitchingDevice is IRouting)
+ {
+ // Pull the route from the port. Whatever is watching the output's in use tracker is
+ // responsible for responding appropriately.
+ route.OutputPort.InUseTracker.RemoveUser(Destination, "destination-" + SignalType);
+ Debug.Console(2, "Port {0} releasing. Count={1}", route.OutputPort.Key, route.OutputPort.InUseTracker.InUseCountFeedback.UShortValue);
+ }
+ }
+ }
+
+ public override string ToString()
+ {
+ var routesText = Routes.Select(r => r.ToString()).ToArray();
+ return string.Format("Route table from {0} to {1}:\r{2}", Source.Key, Destination.Key, string.Join("\r", routesText));
+ }
+ }
+
+ ///
+ /// Represents an individual link for a route
+ ///
+ public class RouteSwitchDescriptor
+ {
+ public IRoutingInputs SwitchingDevice { get { return InputPort.ParentDevice; } }
+ public RoutingOutputPort OutputPort { get; set; }
+ public RoutingInputPort InputPort { get; set; }
+
+ public RouteSwitchDescriptor(RoutingInputPort inputPort)
+ {
+ InputPort = inputPort;
+ }
+
+ public RouteSwitchDescriptor(RoutingOutputPort outputPort, RoutingInputPort inputPort)
+ {
+ InputPort = inputPort;
+ OutputPort = outputPort;
+ }
+
+ public override string ToString()
+ {
+ if(SwitchingDevice is IRouting)
+ return string.Format("{0} switches output '{1}' to input '{2}'", SwitchingDevice.Key, OutputPort.Selector, InputPort.Selector);
+ else
+ return string.Format("{0} switches to input '{1}'", SwitchingDevice.Key, InputPort.Selector);
+
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs
index 467bf045..45245066 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingInterfaces.cs
@@ -204,4 +204,9 @@ namespace PepperDash.Essentials.Core
SigType = sigType;
}
}
+
+ public interface IRoutingHasVideoInputSyncFeedbacks
+ {
+ FeedbackCollection VideoInputSyncFeedbacks { get; }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs
index 79dd4eda..ab64f15e 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPort.cs
@@ -42,7 +42,7 @@ namespace PepperDash.Essentials.Core
public enum eRoutingPortConnectionType
{
None, BackplaneOnly, DisplayPort, Dvi, Hdmi, Rgb, Vga, LineAudio, DigitalAudio, Sdi,
- Composite, Component, DmCat, DmMmFiber, DmSmFiber, Speaker, Streaming
+ Composite, Component, DmCat, DmMmFiber, DmSmFiber, Speaker, Streaming, UsbC, HdBaseT
}
///
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs
index 00e85191..7029443b 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Routing/RoutingPortNames.cs
@@ -199,5 +199,45 @@ namespace PepperDash.Essentials.Core.Routing
/// MediaPlayer
///
public const string MediaPlayer = "mediaPlayer";
- }
+ ///
+ /// UsbCIn
+ ///
+ public const string UsbCIn = "usbCIn";
+ ///
+ /// UsbCIn1
+ ///
+ public const string UsbCIn1 = "usbCIn1";
+ ///
+ /// UsbCIn2
+ ///
+ public const string UsbCIn2 = "usbCIn2";
+ ///
+ /// UsbCIn3
+ ///
+ public const string UsbCIn3 = "usbCIn3";
+ ///
+ /// UsbCOut
+ ///
+ public const string UsbCOut = "usbCOut";
+ ///
+ /// UsbCOut1
+ ///
+ public const string UsbCOut1 = "usbCOut1";
+ ///
+ /// UsbCOut2
+ ///
+ public const string UsbCOut2 = "usbCOut2";
+ ///
+ /// UsbCOut3
+ ///
+ public const string UsbCOut3 = "usbCOut3";
+ ///
+ /// HdBaseTIn
+ ///
+ public const string HdBaseTIn = "hdBaseTIn";
+ ///
+ /// HdBaseTOut
+ ///
+ public const string HdBaseTOut = "hdBaseTOut";
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs
index 95a94a24..8e0cbc55 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs
@@ -148,6 +148,7 @@ namespace PepperDash.Essentials.Core
{
Secrets.Add(key, provider);
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
+ return;
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key );
}
@@ -164,13 +165,13 @@ namespace PepperDash.Essentials.Core
{
Secrets.Add(key, provider);
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
-
+ return;
}
if (overwrite)
{
Secrets.Add(key, provider);
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Provider with the key '{0}' already exists in secrets. Overwriting with new secrets provider.", key);
-
+ return;
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key);
}
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs
index c9a5f605..44a758f8 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Touchpanels/Mpc3Touchpanel.cs
@@ -1,144 +1,371 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
+using System.Globalization;
using Crestron.SimplSharpPro;
-
+using Newtonsoft.Json;
using PepperDash.Core;
-using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Touchpanels
{
- ///
- /// A wrapper class for the touchpanel portion of an MPC3 class process to allow for configurable
- /// behavior of the keybad buttons
- ///
- public class Mpc3TouchpanelController : Device
- {
- MPC3Basic _Touchpanel;
+ ///
+ /// A wrapper class for the touchpanel portion of an MPC3 class process to allow for configurable
+ /// behavior of the keybad buttons
+ ///
+ public class Mpc3TouchpanelController : Device
+ {
+ readonly MPC3Basic _touchpanel;
- Dictionary _Buttons;
+ readonly Dictionary _buttons;
- public Mpc3TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary buttons)
- : base(key, name)
- {
- _Touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic;
- _Buttons = buttons;
+ public Mpc3TouchpanelController(string key, string name, CrestronControlSystem processor, Dictionary buttons)
+ : base(key, name)
+ {
+ _touchpanel = processor.ControllerTouchScreenSlotDevice as MPC3Basic;
+ if (_touchpanel == null)
+ {
+ Debug.Console(1, this, "Failed to construct MPC3 Touchpanel Controller with key {0}, check configuration", key);
+ return;
+ }
- _Touchpanel.ButtonStateChange += new Crestron.SimplSharpPro.DeviceSupport.ButtonEventHandler(_Touchpanel_ButtonStateChange);
+ if (_touchpanel.Registerable)
+ {
+ var registrationResponse = _touchpanel.Register();
+ Debug.Console(0, this, "touchpanel registration response: {0}", registrationResponse);
+ }
- AddPostActivationAction(() =>
- {
- // Link up the button feedbacks to the specified BoolFeedbacks
- foreach (var button in _Buttons)
- {
- var feedbackConfig = button.Value.Feedback;
- var device = DeviceManager.GetDeviceForKey(feedbackConfig.DeviceKey) as Device;
- if (device != null)
- {
- var bKey = button.Key.ToLower();
+ _touchpanel.BaseEvent += _touchpanel_BaseEvent;
+ _touchpanel.ButtonStateChange += _touchpanel_ButtonStateChange;
+ _touchpanel.PanelStateChange += _touchpanel_PanelStateChange;
- var feedback = device.GetFeedbackProperty(feedbackConfig.FeedbackName);
+ _buttons = buttons;
+ if (_buttons == null)
+ {
+ Debug.Console(1, this,
+ "Button properties are null, failed to setup MPC3 Touch Controller, check configuration");
+ return;
+ }
- var bFeedback = feedback as BoolFeedback;
- var iFeedback = feedback as IntFeedback;
- if (bFeedback != null)
- {
+ AddPostActivationAction(() =>
+ {
+ foreach (var button in _buttons)
+ {
+ var buttonKey = button.Key.ToLower();
+ var buttonConfig = button.Value;
- if (bKey == "power")
- {
- bFeedback.LinkCrestronFeedback(_Touchpanel.FeedbackPower);
- continue;
- }
- else if (bKey == "mute")
- {
- bFeedback.LinkCrestronFeedback(_Touchpanel.FeedbackMute);
- continue;
- }
+ InitializeButton(buttonKey, buttonConfig);
+ InitializeButtonFeedback(buttonKey, buttonConfig);
+ }
- // Link to the Crestron Feedback corresponding to the button number
- bFeedback.LinkCrestronFeedback(_Touchpanel.Feedbacks[UInt16.Parse(button.Key)]);
- }
- else if (iFeedback != null)
- {
- if (bKey == "volumefeedback")
- {
- var volFeedback = feedback as IntFeedback;
- // TODO: Figure out how to subsribe to a volume IntFeedback and link it to the voluem
- volFeedback.LinkInputSig(_Touchpanel.VolumeBargraph);
- }
- }
- else
- {
- Debug.Console(1, this, "Unable to get BoolFeedback with name: {0} from device: {1}", feedbackConfig.FeedbackName, device.Key);
- }
- }
- else
- {
- Debug.Console(1, this, "Unable to get device with key: {0}", feedbackConfig.DeviceKey);
- }
- }
- });
- }
+ ListButtons();
+ });
+ }
- void _Touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args)
- {
- Debug.Console(1, this, "Button {0} ({1}), {2}", args.Button.Number, args.Button.Name, args.NewButtonState);
- var type = args.NewButtonState.ToString();
+ ///
+ /// Enables/disables buttons based on event type configuration
+ ///
+ ///
+ ///
+ public void InitializeButton(string key, KeypadButton config)
+ {
+ if (config == null)
+ {
+ Debug.Console(1, this, "Button '{0}' config is null, unable to initialize", key);
+ return;
+ }
- if (_Buttons.ContainsKey(args.Button.Number.ToString()))
- {
- Press(args.Button.Number.ToString(), type);
- }
- else if(_Buttons.ContainsKey(args.Button.Name.ToString()))
- {
- Press(args.Button.Name.ToString(), type);
- }
- }
+ int buttonNumber;
+ TryParseInt(key, out buttonNumber);
- ///
- /// Runs the function associated with this button/type. One of the following strings:
- /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased
- ///
- ///
- ///
- public void Press(string number, string type)
- {
- // TODO: In future, consider modifying this to generate actions at device activation time
- // to prevent the need to dynamically call the method via reflection on each button press
- if (!_Buttons.ContainsKey(number)) { return; }
- var but = _Buttons[number];
- if (but.EventTypes.ContainsKey(type))
- {
- foreach (var a in but.EventTypes[type]) { DeviceJsonApi.DoDeviceAction(a); }
- }
- }
+ var buttonEventTypes = config.EventTypes;
+ BoolOutputSig enabledFb = null;
+ BoolOutputSig disabledFb = null;
+
+ switch (key)
+ {
+ case ("power"):
+ {
+ if (buttonEventTypes == null || buttonEventTypes.Keys == null)
+ _touchpanel.DisablePowerButton();
+ else
+ _touchpanel.EnablePowerButton();
- }
+ enabledFb = _touchpanel.PowerButtonEnabledFeedBack;
+ disabledFb = _touchpanel.PowerButtonDisabledFeedBack;
- ///
- /// Represents the configuration of a keybad buggon
- ///
- public class KeypadButton
- {
- public Dictionary EventTypes { get; set; }
- public KeypadButtonFeedback Feedback { get; set; }
+ break;
+ }
+ //case ("volumeup"):
+ // {
+ // break;
+ // }
+ //case ("volumedown"):
+ // {
+ // break;
+ // }
+ //case ("volumefeedback"):
+ // {
+ // break;
+ // }
+ case ("mute"):
+ {
+ if (buttonEventTypes == null || buttonEventTypes.Keys == null)
+ _touchpanel.DisableMuteButton();
+ else
+ _touchpanel.EnableMuteButton();
- public KeypadButton()
- {
- EventTypes = new Dictionary();
- Feedback = new KeypadButtonFeedback();
- }
- }
- ///
- ///
- ///
- public class KeypadButtonFeedback
- {
- public string DeviceKey { get; set; }
- public string FeedbackName { get; set; }
- }
+ enabledFb = _touchpanel.MuteButtonEnabledFeedBack;
+ disabledFb = _touchpanel.MuteButtonDisabledFeedBack;
+
+ break;
+ }
+ default:
+ {
+ if (buttonNumber == 0 || buttonNumber > 9)
+ break;
+
+ if (buttonEventTypes == null || buttonEventTypes.Keys == null)
+ _touchpanel.DisableNumericalButton((uint)buttonNumber);
+ else
+ _touchpanel.EnableNumericalButton((uint)buttonNumber);
+
+
+ if (_touchpanel.NumericalButtonEnabledFeedBack != null)
+ enabledFb = _touchpanel.NumericalButtonEnabledFeedBack[(uint)buttonNumber];
+
+ if (_touchpanel.NumericalButtonDisabledFeedBack != null)
+ disabledFb = _touchpanel.NumericalButtonDisabledFeedBack[(uint)buttonNumber];
+
+ break;
+ }
+ }
+
+ Debug.Console(0, this, "InitializeButton: key-'{0}' enabledFb-'{1}', disabledFb-'{2}'",
+ key, enabledFb ?? (object)"null", disabledFb ?? (object)"null");
+ }
+
+ ///
+ /// Links button feedback if configured
+ ///
+ ///
+ ///
+ public void InitializeButtonFeedback(string key, KeypadButton config)
+ {
+ //Debug.Console(1, this, "Initializing button '{0}' feedback...", key);
+
+ if (config == null)
+ {
+ Debug.Console(1, this, "Button '{0}' config is null, skipping.", key);
+ return;
+ }
+
+ int buttonNumber;
+ TryParseInt(key, out buttonNumber);
+
+ // Link up the button feedbacks to the specified device feedback
+ var buttonFeedback = config.Feedback;
+ if (buttonFeedback == null || string.IsNullOrEmpty(buttonFeedback.DeviceKey))
+ {
+ Debug.Console(1, this, "Button '{0}' feedback not configured, skipping.",
+ key);
+ return;
+ }
+
+ Feedback deviceFeedback;
+
+ try
+ {
+ var device = DeviceManager.GetDeviceForKey(buttonFeedback.DeviceKey) as Device;
+ if (device == null)
+ {
+ Debug.Console(1, this, "Button '{0}' feedback deviceKey '{1}' not found.",
+ key, buttonFeedback.DeviceKey);
+ return;
+ }
+
+ deviceFeedback = device.GetFeedbackProperty(buttonFeedback.FeedbackName);
+ if (deviceFeedback == null)
+ {
+ Debug.Console(1, this, "Button '{0}' feedbackName property '{1}' not found.",
+ key, buttonFeedback.FeedbackName);
+ return;
+ }
+
+ // TODO [ ] verify if this can replace the current method
+ //Debug.Console(0, this, "deviceFeedback.GetType().Name: '{0}'", deviceFeedback.GetType().Name);
+ //switch (feedback.GetType().Name.ToLower())
+ //{
+ // case("boolfeedback"):
+ // {
+ // break;
+ // }
+ // case("intfeedback"):
+ // {
+ // break;
+ // }
+ // case("stringfeedback"):
+ // {
+ // break;
+ // }
+ //}
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(1, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') Exception Message: {0}",
+ ex.Message, key, buttonFeedback.DeviceKey);
+ Debug.Console(2, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') Exception StackTrace: {0}",
+ ex.StackTrace, key, buttonFeedback.DeviceKey);
+ if (ex.InnerException != null) Debug.Console(2, this, "InitializeButtonFeedback (button '{1}', deviceKey '{2}') InnerException: {0}",
+ ex.InnerException, key, buttonFeedback.DeviceKey);
+
+ return;
+ }
+
+ var boolFeedback = deviceFeedback as BoolFeedback;
+ var intFeedback = deviceFeedback as IntFeedback;
+
+ switch (key)
+ {
+ case ("power"):
+ {
+ if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackPower);
+ break;
+ }
+ case ("volumeup"):
+ case ("volumedown"):
+ case ("volumefeedback"):
+ {
+ if (intFeedback != null)
+ {
+ var volumeFeedback = intFeedback;
+ volumeFeedback.LinkInputSig(_touchpanel.VolumeBargraph);
+ }
+ break;
+ }
+ case ("mute"):
+ {
+ if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.FeedbackMute);
+ break;
+ }
+ default:
+ {
+ if (boolFeedback != null) boolFeedback.LinkCrestronFeedback(_touchpanel.Feedbacks[(uint)buttonNumber]);
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Try parse int helper method
+ ///
+ ///
+ ///
+ ///
+ public bool TryParseInt(string str, out int result)
+ {
+ try
+ {
+ result = int.Parse(str);
+ return true;
+ }
+ catch
+ {
+ result = 0;
+ return false;
+ }
+ }
+
+ private void _touchpanel_BaseEvent(GenericBase device, BaseEventArgs args)
+ {
+ Debug.Console(1, this, "BaseEvent: eventId-'{0}', index-'{1}'", args.EventId, args.Index);
+ }
+
+ private void _touchpanel_ButtonStateChange(GenericBase device, Crestron.SimplSharpPro.DeviceSupport.ButtonEventArgs args)
+ {
+ Debug.Console(1, this, "ButtonStateChange: buttonNumber-'{0}' buttonName-'{1}', buttonState-'{2}'", args.Button.Number, args.Button.Name, args.NewButtonState);
+ var type = args.NewButtonState.ToString();
+
+ if (_buttons.ContainsKey(args.Button.Number.ToString(CultureInfo.InvariantCulture)))
+ {
+ Press(args.Button.Number.ToString(CultureInfo.InvariantCulture), type);
+ }
+ else if (_buttons.ContainsKey(args.Button.Name.ToString()))
+ {
+ Press(args.Button.Name.ToString(), type);
+ }
+ }
+
+ private void _touchpanel_PanelStateChange(GenericBase device, BaseEventArgs args)
+ {
+ Debug.Console(1, this, "PanelStateChange: eventId-'{0}', index-'{1}'", args.EventId, args.Index);
+ }
+
+ ///
+ /// Runs the function associated with this button/type. One of the following strings:
+ /// Pressed, Released, Tapped, DoubleTapped, Held, HeldReleased
+ ///
+ ///
+ ///
+ public void Press(string buttonKey, string type)
+ {
+ Debug.Console(2, this, "Press: buttonKey-'{0}', type-'{1}'", buttonKey, type);
+
+ // TODO: In future, consider modifying this to generate actions at device activation time
+ // to prevent the need to dynamically call the method via reflection on each button press
+ if (!_buttons.ContainsKey(buttonKey)) return;
+
+ var button = _buttons[buttonKey];
+ if (!button.EventTypes.ContainsKey(type)) return;
+
+ foreach (var eventType in button.EventTypes[type]) DeviceJsonApi.DoDeviceAction(eventType);
+ }
+
+
+ public void ListButtons()
+ {
+ var line = new string('-', 35);
+
+ Debug.Console(0, this, line);
+
+ Debug.Console(0, this, "MPC3 Controller {0} - Available Butons", Key);
+
+ foreach (var button in _buttons)
+ {
+ Debug.Console(0, this, "Key: {0}", button.Key);
+ }
+
+ Debug.Console(0, this, line);
+ }
+ }
+
+ ///
+ /// Represents the configuration of a keypad button
+ ///
+ public class KeypadButton
+ {
+ [JsonProperty("eventTypes")]
+ public Dictionary EventTypes { get; set; }
+
+ [JsonProperty("feedback")]
+ public KeypadButtonFeedback Feedback { get; set; }
+
+ public KeypadButton()
+ {
+ EventTypes = new Dictionary();
+ Feedback = new KeypadButtonFeedback();
+ }
+ }
+
+ ///
+ /// Represents the configuration of a keypad button feedback
+ ///
+ public class KeypadButtonFeedback
+ {
+ [JsonProperty("deviceKey")]
+ public string DeviceKey { get; set; }
+
+ [JsonProperty("feedbackName")]
+ public string FeedbackName { get; set; }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI/TouchpanelBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI/TouchpanelBase.cs
index 36e0342e..c7be5048 100644
--- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI/TouchpanelBase.cs
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/UI/TouchpanelBase.cs
@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core.UI
:base(key, name)
{
- if (Panel == null)
+ if (panel == null)
{
Debug.Console(0, this, "Panel is not valid. Touchpanel class WILL NOT work correctly");
return;
@@ -71,6 +71,8 @@ namespace PepperDash.Essentials.Core.UI
return;
}
}
+
+ Panel.LoadSmartObjects(sgdName);
});
AddPostActivationAction(() =>
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs
new file mode 100644
index 00000000..dd2ade1a
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssemtialsWebApi.cs
@@ -0,0 +1,224 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Crestron.SimplSharp;
+using Crestron.SimplSharp.WebScripting;
+using PepperDash.Core;
+using PepperDash.Core.Web;
+using PepperDash.Essentials.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web
+{
+ public class EssemtialsWebApi : EssentialsDevice
+ {
+ private readonly WebApiServer _server;
+
+ ///
+ /// http(s)://{ipaddress}/cws/{basePath}
+ /// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath}
+ ///
+ private readonly string _defaultBasePath = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
+ ? string.Format("/app{0:00}/api", InitialParametersClass.ApplicationNumber)
+ : "/api";
+
+ private const int DebugTrace = 0;
+ private const int DebugInfo = 1;
+ private const int DebugVerbose = 2;
+
+ ///
+ /// CWS base path
+ ///
+ public string BasePath { get; private set; }
+
+ ///
+ /// Tracks if CWS is registered
+ ///
+ public bool IsRegistered
+ {
+ get { return _server.IsRegistered; }
+ }
+
+ ///
+ /// Constructor
+ ///
+ ///
+ ///
+ public EssemtialsWebApi(string key, string name)
+ : this(key, name, null)
+ {
+ }
+
+ ///
+ /// Constructor
+ ///
+ ///
+ ///
+ ///
+ public EssemtialsWebApi(string key, string name, EssentialsWebApiPropertiesConfig config)
+ : base(key, name)
+ {
+ Key = key;
+
+ if (config == null)
+ BasePath = _defaultBasePath;
+ else
+ BasePath = string.IsNullOrEmpty(config.BasePath) ? _defaultBasePath : config.BasePath;
+
+ _server = new WebApiServer(Key, Name, BasePath);
+ }
+
+ ///
+ /// Custom activate, add routes
+ ///
+ ///
+ public override bool CustomActivate()
+ {
+ var routes = new List
+ {
+ new HttpCwsRoute("reportversions")
+ {
+ Name = "ReportVersions",
+ RouteHandler = new ReportVersionsRequestHandler()
+ },
+ new HttpCwsRoute("appdebug")
+ {
+ Name = "AppDebug",
+ RouteHandler = new AppDebugRequestHandler()
+ },
+ new HttpCwsRoute("devlist")
+ {
+ Name = "DevList",
+ RouteHandler = new DevListRequestHandler()
+ },
+ new HttpCwsRoute("devprops")
+ {
+ Name = "DevProps",
+ RouteHandler = new DevPropsRequestHandler()
+ },
+ new HttpCwsRoute("devjson")
+ {
+ Name = "DevJson",
+ RouteHandler = new DevJsonRequestHandler()
+ },
+ new HttpCwsRoute("setdevicestreamdebug")
+ {
+ Name = "SetDeviceStreamDebug",
+ RouteHandler = new SetDeviceStreamDebugRequestHandler()
+ },
+ new HttpCwsRoute("disableallstreamdebug")
+ {
+ Name = "DisableAllStreamDebug",
+ RouteHandler = new DisableAllStreamDebugRequestHandler()
+ },
+ new HttpCwsRoute("showconfig")
+ {
+ Name = "ShowConfig",
+ RouteHandler = new ShowConfigRequestHandler()
+ },
+ new HttpCwsRoute("gettypes")
+ {
+ Name = "GetTypes",
+ RouteHandler = new GetTypesRequestHandler()
+ },
+ new HttpCwsRoute("gettypes/{filter}")
+ {
+ Name = "GetTypesByFilter",
+ RouteHandler = new GetTypesByFilterRequestHandler()
+ },
+ new HttpCwsRoute("getjoinmap/{bridgeKey}")
+ {
+ Name = "GetJoinMapsForBridgeKey",
+ RouteHandler = new GetJoinMapForBridgeKeyRequestHandler()
+ },
+ new HttpCwsRoute("getjoinmap/{bridgeKey}/{deviceKey}")
+ {
+ Name = "GetJoinMapsForDeviceKey",
+ RouteHandler = new GetJoinMapForDeviceKeyRequestHandler()
+ },
+ new HttpCwsRoute("feedbacks/{deviceKey}")
+ {
+ Name = "GetFeedbacksForDeviceKey",
+ RouteHandler = new GetFeedbacksForDeviceRequestHandler()
+ }
+ };
+
+ foreach (var route in routes.Where(route => route != null))
+ {
+ var r = route;
+ _server.AddRoute(r);
+ }
+
+ return base.CustomActivate();
+ }
+
+ ///
+ /// Initializes the CWS class
+ ///
+ public override void Initialize()
+ {
+ // If running on an appliance
+ if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
+ {
+ /*
+ WEBSERVER [ON | OFF | TIMEOUT | MAXSESSIONSPERUSER ]
+ */
+ var response = string.Empty;
+ CrestronConsole.SendControlSystemCommand("webserver", ref response);
+ if (response.Contains("OFF")) return;
+
+ var is4Series = eCrestronSeries.Series4 == (Global.ProcessorSeries & eCrestronSeries.Series4);
+ Debug.Console(DebugTrace, Debug.ErrorLogLevel.Notice, "Starting Essentials Web API on {0} Appliance", is4Series ? "4-series" : "3-series");
+
+ _server.Start();
+
+ GetPaths();
+
+ return;
+ }
+
+ // Automatically start CWS when running on a server (Linux OS, Virtual Control)
+ Debug.Console(DebugTrace, Debug.ErrorLogLevel.Notice, "Starting Essentials Web API on Virtual Control Server");
+
+ _server.Start();
+
+ GetPaths();
+ }
+
+ ///
+ /// Print the available pahts
+ ///
+ ///
+ /// http(s)://{ipaddress}/cws/{basePath}
+ /// http(s)://{ipaddress}/VirtualControl/Rooms/{roomId}/cws/{basePath}
+ ///
+ public void GetPaths()
+ {
+ Debug.Console(DebugTrace, this, "{0}", new String('-', 50));
+
+ var currentIp = CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
+
+ var hostname = CrestronEthernetHelper.GetEthernetParameter(
+ CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
+
+ var path = CrestronEnvironment.DevicePlatform == eDevicePlatform.Server
+ ? string.Format("http(s)://{0}/VirtualControl/Rooms/{1}/cws{2}", hostname, InitialParametersClass.RoomId, BasePath)
+ : string.Format("http(s)://{0}/cws{1}", currentIp, BasePath);
+
+ Debug.Console(DebugTrace, this, "Server:{0}", path);
+
+ var routeCollection = _server.GetRouteCollection();
+ if (routeCollection == null)
+ {
+ Debug.Console(DebugTrace, this, "Server route collection is null");
+ return;
+ }
+ Debug.Console(DebugTrace, this, "Configured Routes:");
+ foreach (var route in routeCollection)
+ {
+ Debug.Console(DebugTrace, this, "{0}: {1}/{2}", route.Name, path, route.Url);
+ }
+ Debug.Console(DebugTrace, this, "{0}", new String('-', 50));
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiFactory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiFactory.cs
new file mode 100644
index 00000000..51361c2c
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiFactory.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+using PepperDash.Core;
+using PepperDash.Essentials.Core.Config;
+
+namespace PepperDash.Essentials.Core.Web
+{
+ public class EssentialsWebApiFactory : EssentialsDeviceFactory
+ {
+ public EssentialsWebApiFactory()
+ {
+ TypeNames = new List { "EssentialsWebApi" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ Debug.Console(1, "Factory Attempting to create new Essentials Web API Server");
+
+ var props = dc.Properties.ToObject();
+ if (props != null) return new EssemtialsWebApi(dc.Key, dc.Name, props);
+
+ Debug.Console(1, "Factory failed to create new Essentials Web API Server");
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiHelpers.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiHelpers.cs
new file mode 100644
index 00000000..4830edb4
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiHelpers.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp.WebScripting;
+using PepperDash.Core;
+
+namespace PepperDash.Essentials.Core.Web
+{
+ public class EssentialsWebApiHelpers
+ {
+ public static string GetRequestBody(HttpCwsRequest request)
+ {
+ var bytes = new Byte[request.ContentLength];
+
+ request.InputStream.Read(bytes, 0, request.ContentLength);
+
+ return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
+ }
+
+ public static object MapToAssemblyObject(LoadedAssembly assembly)
+ {
+ return new
+ {
+ Name = assembly.Name,
+ Version = assembly.Version
+ };
+ }
+
+ public static object MapToDeviceListObject(IKeyed device)
+ {
+ return new
+ {
+ Key = device.Key,
+ Name = (device is IKeyName)
+ ? (device as IKeyName).Name
+ : "---"
+ };
+ }
+
+ public static object MapJoinToObject(string key, JoinMapBaseAdvanced join)
+ {
+ var kp = new KeyValuePair(key, join);
+
+ return MapJoinToObject(kp);
+ }
+
+ public static object MapJoinToObject(KeyValuePair join)
+ {
+ return new
+ {
+ DeviceKey = join.Key,
+ Joins = join.Value.Joins.Select(j => MapJoinDataCompleteToObject(j))
+ };
+ }
+
+ public static object MapJoinDataCompleteToObject(KeyValuePair joinData)
+ {
+ return new
+ {
+ Signal = joinData.Key,
+ Description = joinData.Value.Metadata.Description,
+ JoinNumber = joinData.Value.JoinNumber,
+ JoinSpan = joinData.Value.JoinSpan,
+ JoinType = joinData.Value.Metadata.JoinType.ToString(),
+ JoinCapabilities = joinData.Value.Metadata.JoinCapabilities.ToString()
+ };
+ }
+
+ public static object MapDeviceTypeToObject(string key, DeviceFactoryWrapper device)
+ {
+ var kp = new KeyValuePair(key, device);
+
+ return MapDeviceTypeToObject(kp);
+ }
+
+ public static object MapDeviceTypeToObject(KeyValuePair device)
+ {
+ return new
+ {
+ Type = device.Key,
+ Description = device.Value.Description,
+ CType = device.Value.CType == null ? "---": device.Value.CType.ToString()
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiPropertiesConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiPropertiesConfig.cs
new file mode 100644
index 00000000..a57e1ce9
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/EssentialsWebApiPropertiesConfig.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace PepperDash.Essentials.Core.Web
+{
+ public class EssentialsWebApiPropertiesConfig
+ {
+ [JsonProperty("basePath")]
+ public string BasePath { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/AppDebugRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/AppDebugRequestHandler.cs
new file mode 100644
index 00000000..bbe4bd22
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/AppDebugRequestHandler.cs
@@ -0,0 +1,82 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class AppDebugRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public AppDebugRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var appDebug = new AppDebug { Level = Debug.Level };
+
+ var body = JsonConvert.SerializeObject(appDebug, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.Write(body, false);
+ context.Response.End();
+ }
+
+ ///
+ /// Handles POST method requests
+ ///
+ ///
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ if (context.Request.ContentLength < 0)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var data = EssentialsWebApiHelpers.GetRequestBody(context.Request);
+ if (string.IsNullOrEmpty(data))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var appDebug = new AppDebug();
+ var requestBody = JsonConvert.DeserializeAnonymousType(data, appDebug);
+
+ Debug.SetDebugLevel(requestBody.Level);
+
+ appDebug.Level = Debug.Level;
+ var responseBody = JsonConvert.SerializeObject(appDebug, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.Write(responseBody, false);
+ context.Response.End();
+ }
+ }
+
+ public class AppDebug
+ {
+ [JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
+ public int Level { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs
new file mode 100644
index 00000000..786962f5
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DefaultRequestHandler.cs
@@ -0,0 +1,118 @@
+using Crestron.SimplSharp.WebScripting;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class DefaultRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public DefaultRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles CONNECT method requests
+ ///
+ ///
+ protected override void HandleConnect(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles DELETE method requests
+ ///
+ ///
+ protected override void HandleDelete(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles HEAD method requests
+ ///
+ ///
+ protected override void HandleHead(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles OPTIONS method requests
+ ///
+ ///
+ protected override void HandleOptions(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles PATCH method requests
+ ///
+ ///
+ protected override void HandlePatch(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles POST method requests
+ ///
+ ///
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles PUT method requests
+ ///
+ ///
+ protected override void HandlePut(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles TRACE method requests
+ ///
+ ///
+ protected override void HandleTrace(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 418;
+ context.Response.StatusDescription = "I'm a teapot";
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevJsonRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevJsonRequestHandler.cs
new file mode 100644
index 00000000..7a9162bd
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevJsonRequestHandler.cs
@@ -0,0 +1,66 @@
+using System;
+using Crestron.SimplSharp.WebScripting;
+using PepperDash.Core;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class DevJsonRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public DevJsonRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles POST method requests
+ ///
+ ///
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ if (context.Request.ContentLength < 0)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var data = EssentialsWebApiHelpers.GetRequestBody(context.Request);
+ if (string.IsNullOrEmpty(data))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ try
+ {
+ DeviceJsonApi.DoDeviceActionWithJson(data);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.End();
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(1, "Exception Message: {0}", ex.Message);
+ Debug.Console(2, "Exception Stack Trace: {0}", ex.StackTrace);
+ if(ex.InnerException != null) Debug.Console(2, "Exception Inner: {0}", ex.InnerException);
+
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs
new file mode 100644
index 00000000..cf2a1e78
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevListRequestHandler.cs
@@ -0,0 +1,51 @@
+using System.Linq;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class DevListRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public DevListRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var allDevices = DeviceManager.AllDevices;
+ if (allDevices == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ allDevices.Sort((a, b) => System.String.Compare(a.Key, b.Key, System.StringComparison.Ordinal));
+
+ var deviceList = allDevices.Select(d => EssentialsWebApiHelpers.MapToDeviceListObject(d)).ToList();
+
+ var js = JsonConvert.SerializeObject(deviceList, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevPropsRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevPropsRequestHandler.cs
new file mode 100644
index 00000000..be8d154d
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DevPropsRequestHandler.cs
@@ -0,0 +1,76 @@
+using System.Text;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class DevPropsRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public DevPropsRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles POST method requests
+ ///
+ ///
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ if (context.Request.ContentLength < 0)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var data = EssentialsWebApiHelpers.GetRequestBody(context.Request);
+ if (string.IsNullOrEmpty(data))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var o = new DeviceActionWrapper();
+ var body = JsonConvert.DeserializeAnonymousType(data, o);
+
+ if (string.IsNullOrEmpty(body.DeviceKey))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var deviceProps = DeviceJsonApi.GetProperties(body.DeviceKey);
+ if (deviceProps == null || deviceProps.ToLower().Contains("no device"))
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = Encoding.UTF8;
+ context.Response.Write(deviceProps, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DisableAllStreamDebugRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DisableAllStreamDebugRequestHandler.cs
new file mode 100644
index 00000000..2e4546f4
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/DisableAllStreamDebugRequestHandler.cs
@@ -0,0 +1,32 @@
+using Crestron.SimplSharp.WebScripting;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class DisableAllStreamDebugRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public DisableAllStreamDebugRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles POST method requests
+ ///
+ ///
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ DeviceManager.DisableAllDeviceStreamDebugging();
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetFeedbacksForDeviceRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetFeedbacksForDeviceRequestHandler.cs
new file mode 100644
index 00000000..5d76bc73
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetFeedbacksForDeviceRequestHandler.cs
@@ -0,0 +1,102 @@
+using System.Linq;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class GetFeedbacksForDeviceRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public GetFeedbacksForDeviceRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var routeData = context.Request.RouteData;
+ if (routeData == null)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ object deviceObj;
+ if (!routeData.Values.TryGetValue("deviceKey", out deviceObj))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+
+ var device = DeviceManager.GetDeviceForKey(deviceObj.ToString()) as IHasFeedback;
+ if (device == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ var boolFeedback =
+ from feedback in device.Feedbacks.OfType()
+ where !string.IsNullOrEmpty(feedback.Key)
+ select new
+ {
+ FeedbackKey = feedback.Key,
+ Value = feedback.BoolValue
+ };
+
+ var intFeedback =
+ from feedback in device.Feedbacks.OfType()
+ where !string.IsNullOrEmpty(feedback.Key)
+ select new
+ {
+ FeedbackKey = feedback.Key,
+ Value = feedback.IntValue
+ };
+
+ var stringFeedback =
+ from feedback in device.Feedbacks.OfType()
+ where !string.IsNullOrEmpty(feedback.Key)
+ select new
+ {
+ FeedbackKey = feedback.Key,
+ Value = feedback.StringValue ?? string.Empty
+ };
+
+ var responseObj = new
+ {
+ BoolValues = boolFeedback,
+ IntValues = intFeedback,
+ SerialValues = stringFeedback
+ };
+
+ var js = JsonConvert.SerializeObject(responseObj, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetJoinMapForBridgeKeyRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetJoinMapForBridgeKeyRequestHandler.cs
new file mode 100644
index 00000000..7e15fd5e
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetJoinMapForBridgeKeyRequestHandler.cs
@@ -0,0 +1,78 @@
+using System.Linq;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class GetJoinMapForBridgeKeyRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public GetJoinMapForBridgeKeyRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var routeData = context.Request.RouteData;
+ if (routeData == null)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ object bridgeObj;
+ if (!routeData.Values.TryGetValue("bridgeKey", out bridgeObj))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var bridge = DeviceManager.GetDeviceForKey(bridgeObj.ToString()) as EiscApiAdvanced;
+ if (bridge == null)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var joinMap = bridge.JoinMaps.Select(j => EssentialsWebApiHelpers.MapJoinToObject(j)).ToList();
+ if (joinMap == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ var js = JsonConvert.SerializeObject(joinMap, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetJoinMapForDeviceKeyRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetJoinMapForDeviceKeyRequestHandler.cs
new file mode 100644
index 00000000..77d7f8ea
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetJoinMapForDeviceKeyRequestHandler.cs
@@ -0,0 +1,95 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class GetJoinMapForDeviceKeyRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public GetJoinMapForDeviceKeyRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var routeData = context.Request.RouteData;
+ if (routeData == null)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ object bridgeObj;
+ if (!routeData.Values.TryGetValue("bridgeKey", out bridgeObj))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ object deviceObj;
+ if (!routeData.Values.TryGetValue("deviceKey", out deviceObj))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var bridge = DeviceManager.GetDeviceForKey(bridgeObj.ToString()) as EiscApiAdvanced;
+ if (bridge == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ JoinMapBaseAdvanced deviceJoinMap;
+ if (!bridge.JoinMaps.TryGetValue(deviceObj.ToString(), out deviceJoinMap))
+ {
+ context.Response.StatusCode = 500;
+ context.Response.StatusDescription = "Internal Server Error";
+ context.Response.End();
+
+ return;
+ }
+
+ var joinMap = EssentialsWebApiHelpers.MapJoinToObject(deviceObj.ToString(), deviceJoinMap);
+ var js = JsonConvert.SerializeObject(joinMap, Formatting.Indented, new JsonSerializerSettings
+ {
+ ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
+ NullValueHandling = NullValueHandling.Ignore,
+ MissingMemberHandling = MissingMemberHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Ignore,
+ TypeNameHandling = TypeNameHandling.None
+ });
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetTypesByFilterRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetTypesByFilterRequestHandler.cs
new file mode 100644
index 00000000..706793e7
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetTypesByFilterRequestHandler.cs
@@ -0,0 +1,68 @@
+using System.Linq;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class GetTypesByFilterRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public GetTypesByFilterRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var routeData = context.Request.RouteData;
+ if (routeData == null)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ object filterObj;
+ if (!routeData.Values.TryGetValue("filter", out filterObj))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var deviceFactory = DeviceFactory.GetDeviceFactoryDictionary(filterObj.ToString());
+ if (deviceFactory == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ var deviceTypes = deviceFactory.Select(t => EssentialsWebApiHelpers.MapDeviceTypeToObject(t)).ToList();
+ var js = JsonConvert.SerializeObject(deviceTypes, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetTypesRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetTypesRequestHandler.cs
new file mode 100644
index 00000000..9d5f1150
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/GetTypesRequestHandler.cs
@@ -0,0 +1,58 @@
+using System.Linq;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class GetTypesRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public GetTypesRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var routeData = context.Request.RouteData;
+ if (routeData == null)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var deviceFactory = DeviceFactory.GetDeviceFactoryDictionary(null);
+ if (deviceFactory == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ var deviceTypes = deviceFactory.Select(t => EssentialsWebApiHelpers.MapDeviceTypeToObject(t)).ToList();
+ var js = JsonConvert.SerializeObject(deviceTypes, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs
new file mode 100644
index 00000000..e6fb45f1
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ReportVersionsRequestHandler.cs
@@ -0,0 +1,49 @@
+using System.Linq;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class ReportVersionsRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public ReportVersionsRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var loadAssemblies = PluginLoader.LoadedAssemblies;
+ if (loadAssemblies == null)
+ {
+ context.Response.StatusCode = 500;
+ context.Response.StatusDescription = "Internal Server Error";
+ context.Response.End();
+
+ return;
+ }
+
+ var assemblies = loadAssemblies.Select(a => EssentialsWebApiHelpers.MapToAssemblyObject(a)).ToList();
+
+ var js = JsonConvert.SerializeObject(assemblies, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(js, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs
new file mode 100644
index 00000000..bb7cc12f
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/SetDeviceStreamDebugRequestHandler.cs
@@ -0,0 +1,212 @@
+using System;
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Core.Web.RequestHandlers;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class SetDeviceStreamDebugRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Handles CONNECT method requests
+ ///
+ ///
+ protected override void HandleConnect(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles DELETE method requests
+ ///
+ ///
+ protected override void HandleDelete(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles HEAD method requests
+ ///
+ ///
+ protected override void HandleHead(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles OPTIONS method requests
+ ///
+ ///
+ protected override void HandleOptions(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles PATCH method requests
+ ///
+ ///
+ protected override void HandlePatch(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles POST method requests
+ ///
+ ///
+ protected override void HandlePost(HttpCwsContext context)
+ {
+ if (context.Request.ContentLength < 0)
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var data = EssentialsWebApiHelpers.GetRequestBody(context.Request);
+ if (data == null)
+ {
+ context.Response.StatusCode = 500;
+ context.Response.StatusDescription = "Internal Server Error";
+ context.Response.End();
+
+ return;
+ }
+
+ var config = new SetDeviceStreamDebugConfig();
+ var body = JsonConvert.DeserializeAnonymousType(data, config);
+ if (body == null)
+ {
+ context.Response.StatusCode = 500;
+ context.Response.StatusDescription = "Internal Server Error";
+ context.Response.End();
+
+ return;
+ }
+
+ if (string.IsNullOrEmpty(body.DeviceKey) || string.IsNullOrEmpty(body.Setting))
+ {
+ context.Response.StatusCode = 400;
+ context.Response.StatusDescription = "Bad Request";
+ context.Response.End();
+
+ return;
+ }
+
+ var device = DeviceManager.GetDeviceForKey(body.DeviceKey) as IStreamDebugging;
+ if (device == null)
+ {
+ context.Response.StatusCode = 404;
+ context.Response.StatusDescription = "Not Found";
+ context.Response.End();
+
+ return;
+ }
+
+ eStreamDebuggingSetting debugSetting;
+ try
+ {
+ debugSetting = (eStreamDebuggingSetting) Enum.Parse(typeof (eStreamDebuggingSetting), body.Setting, true);
+ }
+ catch (Exception ex)
+ {
+ context.Response.StatusCode = 500;
+ context.Response.StatusDescription = "Internal Server Error";
+ context.Response.End();
+
+ return;
+ }
+
+ try
+ {
+ var mins = Convert.ToUInt32(body.Timeout);
+ if (mins > 0)
+ {
+ device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, mins);
+ }
+ else
+ {
+ device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
+ }
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.End();
+ }
+ catch (Exception ex)
+ {
+ context.Response.StatusCode = 500;
+ context.Response.StatusDescription = "Internal Server Error";
+ context.Response.End();
+ }
+ }
+
+ ///
+ /// Handles PUT method requests
+ ///
+ ///
+ protected override void HandlePut(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+
+ ///
+ /// Handles TRACE method requests
+ ///
+ ///
+ protected override void HandleTrace(HttpCwsContext context)
+ {
+ context.Response.StatusCode = 501;
+ context.Response.StatusDescription = "Not Implemented";
+ context.Response.End();
+ }
+ }
+
+
+ public class SetDeviceStreamDebugConfig
+ {
+ [JsonProperty("deviceKey", NullValueHandling = NullValueHandling.Include)]
+ public string DeviceKey { get; set; }
+
+ [JsonProperty("setting", NullValueHandling = NullValueHandling.Include)]
+ public string Setting { get; set; }
+
+ [JsonProperty("timeout")]
+ public int Timeout { get; set; }
+
+ public SetDeviceStreamDebugConfig()
+ {
+ DeviceKey = null;
+ Setting = null;
+ Timeout = 15;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ShowConfigRequestHandler.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ShowConfigRequestHandler.cs
new file mode 100644
index 00000000..89da86b3
--- /dev/null
+++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Web/RequestHandlers/ShowConfigRequestHandler.cs
@@ -0,0 +1,37 @@
+using Crestron.SimplSharp.WebScripting;
+using Newtonsoft.Json;
+using PepperDash.Core.Web.RequestHandlers;
+using PepperDash.Essentials.Core.Config;
+
+namespace PepperDash.Essentials.Core.Web.RequestHandlers
+{
+ public class ShowConfigRequestHandler : WebApiBaseRequestHandler
+ {
+ ///
+ /// Constructor
+ ///
+ ///
+ /// base(true) enables CORS support by default
+ ///
+ public ShowConfigRequestHandler()
+ : base(true)
+ {
+ }
+
+ ///
+ /// Handles GET method requests
+ ///
+ ///
+ protected override void HandleGet(HttpCwsContext context)
+ {
+ var config = JsonConvert.SerializeObject(ConfigReader.ConfigObject, Formatting.Indented);
+
+ context.Response.StatusCode = 200;
+ context.Response.StatusDescription = "OK";
+ context.Response.ContentType = "application/json";
+ context.Response.ContentEncoding = System.Text.Encoding.UTF8;
+ context.Response.Write(config, false);
+ context.Response.End();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs b/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs
index ce2204fe..5a1d50ff 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/AirMedia/AirMediaController.cs
@@ -19,7 +19,7 @@ namespace PepperDash.Essentials.DM.AirMedia
[Description("Wrapper class for an AM-200 or AM-300")]
public class AirMediaController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IIROutputPorts, IComPorts
{
- public AmX00 AirMedia { get; private set; }
+ public Am3x00 AirMedia { get; private set; }
public DeviceConfig DeviceConfig { get; private set; }
@@ -43,11 +43,12 @@ namespace PepperDash.Essentials.DM.AirMedia
public BoolFeedback HdmiVideoSyncDetectedFeedback { get; private set; }
public StringFeedback SerialNumberFeedback { get; private set; }
public BoolFeedback AutomaticInputRoutingEnabledFeedback { get; private set; }
+ public BoolFeedback HdmiInHdcpSupportOnFeedback { get; private set; }
+ public BoolFeedback HdmiInDisabledByHdcpFeedback { get; private set; }
- public AirMediaController(string key, string name, AmX00 device, DeviceConfig dc, AirMediaPropertiesConfig props)
+ public AirMediaController(string key, string name, Am3x00 device, DeviceConfig dc, AirMediaPropertiesConfig props)
: base(key, name, device)
{
-
AirMedia = device;
DeviceConfig = dc;
@@ -95,24 +96,33 @@ namespace PepperDash.Essentials.DM.AirMedia
AirMedia.AirMedia.AirMediaChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(AirMedia_AirMediaChange);
- IsInSessionFeedback = new BoolFeedback(new Func(() => AirMedia.AirMedia.StatusFeedback.UShortValue == 0));
- ErrorFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.ErrorFeedback.UShortValue));
- NumberOfUsersConnectedFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.NumberOfUsersConnectedFeedback.UShortValue));
- LoginCodeFeedback = new IntFeedback(new Func(() => AirMedia.AirMedia.LoginCodeFeedback.UShortValue));
- ConnectionAddressFeedback = new StringFeedback(new Func(() => AirMedia.AirMedia.ConnectionAddressFeedback.StringValue));
- HostnameFeedback = new StringFeedback(new Func(() => AirMedia.AirMedia.HostNameFeedback.StringValue));
+ IsInSessionFeedback = new BoolFeedback(() => AirMedia.AirMedia.StatusFeedback.UShortValue == 0);
+ ErrorFeedback = new IntFeedback(() => AirMedia.AirMedia.ErrorFeedback.UShortValue);
+ NumberOfUsersConnectedFeedback = new IntFeedback(() => AirMedia.AirMedia.NumberOfUsersConnectedFeedback.UShortValue);
+ LoginCodeFeedback = new IntFeedback(() => AirMedia.AirMedia.LoginCodeFeedback.UShortValue);
+ ConnectionAddressFeedback = new StringFeedback(() => AirMedia.AirMedia.ConnectionAddressFeedback.StringValue);
+ HostnameFeedback = new StringFeedback(() => AirMedia.AirMedia.HostNameFeedback.StringValue);
+ HdmiInHdcpSupportOnFeedback = new BoolFeedback(() => AirMedia.HdmiIn.HdcpSupportOnFeedback.BoolValue);
+ HdmiInDisabledByHdcpFeedback = new BoolFeedback(() => AirMedia.HdmiIn.DisabledByHdcpFeedback.BoolValue);
// TODO: Figure out if we can actually get the TSID/Serial
- SerialNumberFeedback = new StringFeedback(new Func(() => "unknown"));
+ SerialNumberFeedback = new StringFeedback(() => "unknown");
- AirMedia.DisplayControl.DisplayControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(DisplayControl_DisplayControlChange);
+ AirMedia.DisplayControl.DisplayControlChange += DisplayControl_DisplayControlChange;
- VideoOutFeedback = new IntFeedback(new Func(() => Convert.ToInt16(AirMedia.DisplayControl.VideoOutFeedback)));
- AutomaticInputRoutingEnabledFeedback = new BoolFeedback(new Func(() => AirMedia.DisplayControl.EnableAutomaticRoutingFeedback.BoolValue));
+ VideoOutFeedback = new IntFeedback(() => Convert.ToInt16(AirMedia.DisplayControl.VideoOutFeedback));
+ AutomaticInputRoutingEnabledFeedback = new BoolFeedback(() => AirMedia.DisplayControl.EnableAutomaticRoutingFeedback.BoolValue);
- AirMedia.HdmiIn.StreamChange += new Crestron.SimplSharpPro.DeviceSupport.StreamEventHandler(HdmiIn_StreamChange);
+ // Not all AirMedia versions support HDMI In like the 3200
+ if (AirMedia.HdmiIn != null)
+ {
+ AirMedia.HdmiIn.StreamChange += HdmiIn_StreamChange;
+ HdmiVideoSyncDetectedFeedback = new BoolFeedback(() => AirMedia.HdmiIn.SyncDetectedFeedback.BoolValue);
+ return;
+ }
- HdmiVideoSyncDetectedFeedback = new BoolFeedback(new Func(() => AirMedia.HdmiIn.SyncDetectedFeedback.BoolValue));
+ // Return false if the AirMedia device doesn't support HDMI Input
+ HdmiVideoSyncDetectedFeedback = new BoolFeedback(() => false);
}
public override bool CustomActivate()
@@ -171,6 +181,13 @@ namespace PepperDash.Essentials.DM.AirMedia
ConnectionAddressFeedback.LinkInputSig(trilist.StringInput[joinMap.ConnectionAddressFB.JoinNumber]);
HostnameFeedback.LinkInputSig(trilist.StringInput[joinMap.HostnameFB.JoinNumber]);
SerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.SerialNumberFeedback.JoinNumber]);
+
+ trilist.SetSigFalseAction(joinMap.HdmiInHdcpSupportOn.JoinNumber, () => SetHcdpSupport(true));
+ HdmiInHdcpSupportOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.HdmiInHdcpSupportOn.JoinNumber]);
+ trilist.SetSigFalseAction(joinMap.HdmiInHdcpSupportOff.JoinNumber, () => SetHcdpSupport(false));
+ HdmiInHdcpSupportOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.HdmiInHdcpSupportOff.JoinNumber]);
+
+ HdmiInDisabledByHdcpFeedback.LinkInputSig(trilist.BooleanInput[joinMap.HdmiInDisabledByHdcp.JoinNumber]);
}
///
@@ -179,31 +196,53 @@ namespace PepperDash.Essentials.DM.AirMedia
/// Arguments defined as IKeyName sender, output, input, and eRoutingSignalType
private void OnSwitchChange(RoutingNumericEventArgs e)
{
- var newEvent = NumericSwitchChange;
- if (newEvent != null) newEvent(this, e);
- }
+ var handler = NumericSwitchChange;
+
+ if (handler == null) return;
+
+ handler(this, e);
+ }
void AirMedia_AirMediaChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{
- if (args.EventId == AirMediaInputSlot.AirMediaStatusFeedbackEventId)
- IsInSessionFeedback.FireUpdate();
- else if (args.EventId == AirMediaInputSlot.AirMediaErrorFeedbackEventId)
- ErrorFeedback.FireUpdate();
- else if (args.EventId == AirMediaInputSlot.AirMediaNumberOfUserConnectedEventId)
- NumberOfUsersConnectedFeedback.FireUpdate();
- else if (args.EventId == AirMediaInputSlot.AirMediaLoginCodeEventId)
- LoginCodeFeedback.FireUpdate();
- else if (args.EventId == AirMediaInputSlot.AirMediaConnectionAddressFeedbackEventId)
- ConnectionAddressFeedback.FireUpdate();
- else if (args.EventId == AirMediaInputSlot.AirMediaHostNameFeedbackEventId)
- HostnameFeedback.FireUpdate();
+ switch (args.EventId)
+ {
+ case AirMediaInputSlot.AirMediaStatusFeedbackEventId:
+ {
+ IsInSessionFeedback.FireUpdate();
+ break;
+ }
+ case AirMediaInputSlot.AirMediaErrorFeedbackEventId:
+ {
+ ErrorFeedback.FireUpdate();
+ break;
+ }
+ case AirMediaInputSlot.AirMediaNumberOfUserConnectedEventId:
+ {
+ NumberOfUsersConnectedFeedback.FireUpdate();
+ break;
+ }
+ case AirMediaInputSlot.AirMediaLoginCodeEventId:
+ {
+ LoginCodeFeedback.FireUpdate();
+ break;
+ }
+ case AirMediaInputSlot.AirMediaConnectionAddressFeedbackEventId:
+ {
+ ConnectionAddressFeedback.FireUpdate();
+ break;
+ }
+ case AirMediaInputSlot.AirMediaHostNameFeedbackEventId:
+ {
+ HostnameFeedback.FireUpdate();
+ break;
+ }
+ }
}
void DisplayControl_DisplayControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
{
- if (args.EventId == AmX00.VideoOutFeedbackEventId)
- {
VideoOutFeedback.FireUpdate();
var localInputPort =
@@ -211,8 +250,7 @@ namespace PepperDash.Essentials.DM.AirMedia
OnSwitchChange(new RoutingNumericEventArgs(1, VideoOutFeedback.UShortValue, OutputPorts.First(),
localInputPort, eRoutingSignalType.AudioVideo));
- }
- else if (args.EventId == AmX00.EnableAutomaticRoutingFeedbackEventId)
+
AutomaticInputRoutingEnabledFeedback.FireUpdate();
}
@@ -220,6 +258,14 @@ namespace PepperDash.Essentials.DM.AirMedia
{
if (args.EventId == DMInputEventIds.SourceSyncEventId)
HdmiVideoSyncDetectedFeedback.FireUpdate();
+ else if (args.EventId == DMInputEventIds.HdcpSupportOnEventId)
+ {
+ HdmiInHdcpSupportOnFeedback.FireUpdate();
+ }
+ else if (args.EventId == DMInputEventIds.DisabledByHdcpEventId)
+ {
+ HdmiInDisabledByHdcpFeedback.FireUpdate();
+ }
}
///
@@ -268,6 +314,14 @@ namespace PepperDash.Essentials.DM.AirMedia
AirMedia.DisplayControl.VideoOut = AmX00DisplayControl.eAirMediaX00VideoSource.AirBoard;
}
+ public void SetHcdpSupport(bool on)
+ {
+ if (on)
+ AirMedia.HdmiIn.HdcpSupportOn();
+ else
+ AirMedia.HdmiIn.HdcpSupportOff();
+ }
+
///
/// Reboots the device
///
@@ -342,7 +396,7 @@ namespace PepperDash.Essentials.DM.AirMedia
{
public AirMediaControllerFactory()
{
- TypeNames = new List() { "am200", "am300" };
+ TypeNames = new List() { "am200", "am300", "am3200" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -351,12 +405,26 @@ namespace PepperDash.Essentials.DM.AirMedia
Debug.Console(1, "Factory Attempting to create new AirMedia Device");
- var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
- AmX00 amDevice = null;
- if (type == "am200")
- amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am200(props.Control.IpIdInt, Global.ControlSystem);
- else if (type == "am300")
- amDevice = new Crestron.SimplSharpPro.DM.AirMedia.Am300(props.Control.IpIdInt, Global.ControlSystem);
+ var props = dc.Properties.ToObject();
+ Am3x00 amDevice = null;
+ switch (type)
+ {
+ case "am200" :
+ {
+ amDevice = new Am200(props.Control.IpIdInt, Global.ControlSystem);
+ break;
+ }
+ case "am300" :
+ {
+ amDevice = new Am300(props.Control.IpIdInt, Global.ControlSystem);
+ break;
+ }
+ case "am3200" :
+ {
+ amDevice = new Am3200(props.Control.IpIdInt, Global.ControlSystem);
+ break;
+ }
+ }
return new AirMediaController(dc.Key, dc.Name, amDevice, dc, props);
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs
index 412dee6b..3898201d 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmBladeChassisController.cs
@@ -22,7 +22,7 @@ namespace PepperDash.Essentials.DM
/// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
///
///
- public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback
+ public class DmBladeChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitchWithEndpointOnlineFeedback, IRoutingNumericWithFeedback
{
private const string NonePortKey = "inputCard0--None";
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs
index 60ef9d69..ca8b3dd8 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/DmChassisController.cs
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.DM
///
///
[Description("Wrapper class for all DM-MD chassis variants from 8x8 to 32x32")]
- public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitch, IRoutingNumericWithFeedback
+ public class DmChassisController : CrestronGenericBridgeableBaseDevice, IDmSwitchWithEndpointOnlineFeedback, IRoutingNumericWithFeedback
{
private const string NonePortKey = "inputCard0--None";
public DMChassisPropertiesConfig PropertiesConfig { get; set; }
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs
new file mode 100644
index 00000000..7d27d35b
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxAnalogAuxMixerController.cs
@@ -0,0 +1,185 @@
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash_Essentials_DM.Chassis
+{
+ public class HdPsXxxAnalogAuxMixerController : IKeyed,
+ IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback
+ {
+ public string Key { get; private set; }
+
+ private readonly HdPsXxxAnalogAuxMixer _mixer;
+
+ public HdPsXxxAnalogAuxMixerController(string parent, uint mixer, HdPsXxx chassis)
+ {
+ Key = string.Format("{0}-analogMixer{1}", parent, mixer);
+
+ _mixer = chassis.AnalogAuxiliaryMixer[mixer];
+
+ _mixer.AuxMixerPropertyChange += OnAuxMixerPropertyChange;
+ _mixer.AuxiliaryMuteControl.MuteAndVolumeControlPropertyChange += OnMuteAndVolumeControlPropertyChange;
+
+ VolumeLevelFeedback = new IntFeedback(() => VolumeLevel);
+ MuteFeedback = new BoolFeedback(() => IsMuted);
+ }
+
+ #region Volume
+
+ private void OnAuxMixerPropertyChange(object sender, GenericEventArgs args)
+ {
+ Debug.Console(2, this, "OnAuxMixerPropertyChange: {0} > Index-{1}, EventId-{2}", sender.ToString(), args.Index, args.EventId);
+
+ switch (args.EventId)
+ {
+ case MuteAndVolumeContorlEventIds.VolumeFeedbackEventId:
+ {
+ VolumeLevel = _mixer.VolumeFeedback.ShortValue;
+ break;
+ }
+ case MuteAndVolumeContorlEventIds.MuteOnEventId:
+ case MuteAndVolumeContorlEventIds.MuteOffEventId:
+ {
+ IsMuted = _mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue;
+ break;
+ }
+ default:
+ {
+ Debug.Console(1, this, "OnAuxMixerPropertyChange: {0} > Index-{1}, EventId-{2} - unhandled eventId", sender.ToString(), args.Index, args.EventId);
+ break;
+ }
+ }
+ }
+
+ private const ushort CrestronLevelMin = 0;
+ private const ushort CrestronLevelMax = 65535;
+
+ private const int DeviceLevelMin = -800;
+ private const int DeviceLevelMax = 200;
+
+ private const int RampTime = 5000;
+
+ private int _volumeLevel;
+
+ public int VolumeLevel
+ {
+ get { return _volumeLevel; }
+ private set
+ {
+ var level = value;
+
+ _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin);
+
+ Debug.Console(1, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel);
+
+ VolumeLevelFeedback.FireUpdate();
+ }
+ }
+
+ public IntFeedback VolumeLevelFeedback { get; private set; }
+
+ public void SetVolume(ushort level)
+ {
+ var levelScaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin);
+
+ Debug.Console(1, this, "SetVolume: level-'{0}', levelScaled-'{1}'", level, levelScaled);
+
+ _mixer.Volume.ShortValue = (short)levelScaled;
+ }
+
+ public void VolumeUp(bool pressRelease)
+ {
+ if (pressRelease)
+ {
+ _mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime);
+ }
+ else
+ {
+ _mixer.Volume.StopRamp();
+ }
+ }
+
+ public void VolumeDown(bool pressRelease)
+ {
+ if (pressRelease)
+ {
+ _mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime);
+ }
+ else
+ {
+ _mixer.Volume.StopRamp();
+ }
+ }
+
+ #endregion
+
+
+
+
+ #region Mute
+
+ private void OnMuteAndVolumeControlPropertyChange(MuteControl device, GenericEventArgs args)
+ {
+ Debug.Console(2, this, "OnMuteAndVolumeControlPropertyChange: {0} > Index-{1}, EventId-{2}", device.ToString(), args.Index, args.EventId);
+
+ switch (args.EventId)
+ {
+ case MuteAndVolumeContorlEventIds.VolumeFeedbackEventId:
+ {
+ VolumeLevel = _mixer.VolumeFeedback.ShortValue;
+ break;
+ }
+ case MuteAndVolumeContorlEventIds.MuteOnEventId:
+ case MuteAndVolumeContorlEventIds.MuteOffEventId:
+ {
+ IsMuted = _mixer.AuxiliaryMuteControl.MuteOnFeedback.BoolValue;
+ break;
+ }
+ default:
+ {
+ Debug.Console(1, this, "OnMuteAndVolumeControlPropertyChange: {0} > Index-{1}, EventId-{2} - unhandled eventId", device.ToString(), args.Index, args.EventId);
+ break;
+ }
+ }
+ }
+
+ private bool _isMuted;
+
+ public bool IsMuted
+ {
+ get { return _isMuted; }
+ set
+ {
+ _isMuted = value;
+
+ Debug.Console(1, this, "IsMuted: _isMuted-'{0}'", _isMuted);
+
+ MuteFeedback.FireUpdate();
+ }
+ }
+
+ public BoolFeedback MuteFeedback { get; private set; }
+
+ public void MuteOn()
+ {
+ _mixer.AuxiliaryMuteControl.MuteOn();
+ }
+
+ public void MuteOff()
+ {
+ _mixer.AuxiliaryMuteControl.MuteOff();
+ }
+
+ public void MuteToggle()
+ {
+ if (IsMuted)
+ MuteOff();
+ else
+ MuteOn();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs
new file mode 100644
index 00000000..c267acea
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxController.cs
@@ -0,0 +1,646 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Newtonsoft.Json;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.Core.Config;
+using PepperDash_Essentials_Core.Bridges;
+using PepperDash_Essentials_DM.Config;
+
+namespace PepperDash_Essentials_DM.Chassis
+{
+ [Description("Wrapper class for all HdPsXxx switchers")]
+ public class HdPsXxxController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IRoutingHasVideoInputSyncFeedbacks
+ {
+ private readonly HdPsXxx _chassis;
+
+ public RoutingPortCollection InputPorts { get; private set; }
+ public RoutingPortCollection OutputPorts { get; private set; }
+
+ public Dictionary InputNames { get; set; }
+ public Dictionary OutputNames { get; set; }
+
+ public FeedbackCollection InputNameFeedbacks { get; private set; }
+ public FeedbackCollection InputHdcpEnableFeedback { get; private set; }
+
+ public FeedbackCollection OutputNameFeedbacks { get; private set; }
+ public FeedbackCollection OutputRouteNameFeedback { get; private set; }
+
+ public FeedbackCollection VideoInputSyncFeedbacks { get; private set; }
+ public FeedbackCollection VideoOutputRouteFeedbacks { get; private set; }
+
+ public StringFeedback DeviceNameFeedback { get; private set; }
+ public BoolFeedback AutoRouteFeedback { get; private set; }
+
+ public event EventHandler NumericSwitchChange;
+ public event EventHandler DmInputChange;
+
+
+ ///
+ /// Constructor
+ ///
+ ///
+ ///
+ /// HdPs401 device instance
+ ///
+ public HdPsXxxController(string key, string name, HdPsXxx chassis, HdPsXxxPropertiesConfig props)
+ : base(key, name, chassis)
+ {
+ _chassis = chassis;
+ Name = name;
+
+ if (props == null)
+ {
+ Debug.Console(1, this, "HdPsXxxController properties are null, failed to build device");
+ return;
+ }
+
+ InputPorts = new RoutingPortCollection();
+ InputNameFeedbacks = new FeedbackCollection();
+ InputHdcpEnableFeedback = new FeedbackCollection();
+ InputNames = new Dictionary();
+
+ OutputPorts = new RoutingPortCollection();
+ OutputNameFeedbacks = new FeedbackCollection();
+ OutputRouteNameFeedback = new FeedbackCollection();
+ OutputNames = new Dictionary();
+
+ VideoInputSyncFeedbacks = new FeedbackCollection();
+ VideoOutputRouteFeedbacks = new FeedbackCollection();
+
+ if (_chassis.NumberOfOutputs == 1)
+ AutoRouteFeedback = new BoolFeedback(() => _chassis.PriorityRouteOnFeedback.BoolValue);
+
+ InputNames = props.Inputs;
+ SetupInputs(InputNames);
+
+ OutputNames = props.Outputs;
+ SetupOutputs(OutputNames);
+
+ foreach (var item in _chassis.HdmiDmLiteOutputs)
+ {
+ var audioDevice = new HdPsXxxOutputAudioController(Key, item.Number, _chassis);
+ Debug.Console(2, this, "Adding HdPsXxxOutputAudioController '{0}' for output '{1}'", audioDevice.Key, item.Number);
+ DeviceManager.AddDevice(audioDevice);
+ }
+ foreach (var item in _chassis.AnalogAuxiliaryMixer)
+ {
+ var audioDevice = new HdPsXxxAnalogAuxMixerController(Key, item.MixerNumber, _chassis);
+ Debug.Console(2, this, "Adding HdPsXxAnalogAuxMixerCOntorller '{0}' for output '{1}'", audioDevice.Key, item.MixerNumber);
+ DeviceManager.AddDevice(audioDevice);
+ }
+ }
+
+ // get input priorities
+ private byte[] SetInputPriorities(HdPsXxxPropertiesConfig props)
+ {
+ throw new NotImplementedException();
+ }
+
+ // input setup
+ private void SetupInputs(Dictionary dict)
+ {
+ if (dict == null)
+ {
+ Debug.Console(1, this, "Failed to setup inputs, properties are null");
+ return;
+ }
+
+ // iterate through HDMI inputs
+ foreach (var item in _chassis.HdmiInputs)
+ {
+ var input = item;
+ var index = item.Number;
+ var key = string.Format("hdmiIn{0}", index);
+ var name = string.IsNullOrEmpty(InputNames[index])
+ ? string.Format("HDMI Input {0}", index)
+ : InputNames[index];
+
+ input.Name.StringValue = name;
+
+ InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => InputNames[index]));
+
+ var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this)
+ {
+ FeedbackMatchObject = input
+ };
+ Debug.Console(1, this, "Adding Input port: {0} - {1}", port.Key, name);
+ InputPorts.Add(port);
+
+ InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => input.InputPort.HdcpSupportOnFeedback.BoolValue));
+
+ VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => input.InputPort.SyncDetectedFeedback.BoolValue));
+ }
+
+ // iterate through DM Lite inputs
+ foreach (var item in _chassis.DmLiteInputs)
+ {
+ var input = item;
+ var index = item.Number;
+ var key = string.Format("dmLiteIn{0}", index);
+ var name = string.IsNullOrEmpty(InputNames[index])
+ ? string.Format("DM Input {0}", index)
+ : InputNames[index];
+
+ input.Name.StringValue = name;
+
+ InputNameFeedbacks.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => InputNames[index]));
+
+ var port = new RoutingInputPort(key, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, input, this)
+ {
+ FeedbackMatchObject = input
+ };
+ Debug.Console(0, this, "Adding Input port: {0} - {1}", port.Key, name);
+ InputPorts.Add(port);
+
+ InputHdcpEnableFeedback.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => input.InputPort.HdcpSupportOnFeedback.BoolValue));
+
+ VideoInputSyncFeedbacks.Add(new BoolFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => input.InputPort.SyncDetectedFeedback.BoolValue));
+ }
+
+ _chassis.DMInputChange += _chassis_InputChange;
+ }
+
+ // output setup
+ private void SetupOutputs(Dictionary dict)
+ {
+ if (dict == null)
+ {
+ Debug.Console(1, this, "Failed to setup outputs, properties are null");
+ return;
+ }
+
+ foreach (var item in _chassis.HdmiDmLiteOutputs)
+ {
+ var output = item;
+ var index = item.Number;
+ var name = string.IsNullOrEmpty(OutputNames[index])
+ ? string.Format("Port {0}", index)
+ : OutputNames[index];
+
+ output.Name.StringValue = name;
+
+ var hdmiKey = string.Format("hdmiOut{0}", index);
+ var hdmiPort = new RoutingOutputPort(hdmiKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, output, this)
+ {
+ FeedbackMatchObject = output,
+ Port = output.HdmiOutput.HdmiOutputPort
+ };
+ Debug.Console(1, this, "Adding Port port: {0} - {1}", hdmiPort.Key, name);
+ OutputPorts.Add(hdmiPort);
+
+ var dmLiteKey = string.Format("dmLiteOut{0}", index);
+ var dmLitePort = new RoutingOutputPort(dmLiteKey, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.DmCat, output, this)
+ {
+ FeedbackMatchObject = output,
+ Port = output.DmLiteOutput.DmLiteOutputPort
+ };
+ Debug.Console(1, this, "Adding Port port: {0} - {1}", dmLitePort.Key, name);
+ OutputPorts.Add(dmLitePort);
+
+ OutputRouteNameFeedback.Add(new StringFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => output.VideoOutFeedback.NameFeedback.StringValue));
+
+ VideoOutputRouteFeedbacks.Add(new IntFeedback(index.ToString(CultureInfo.InvariantCulture),
+ () => output.VideoOutFeedback == null ? 0 : (int)output.VideoOutFeedback.Number));
+ }
+ /*
+ Debug.Console(2, this, "----> AnalogAuxillaryMixer.Count-{0}", _chassis.AnalogAuxiliaryMixer.Count);
+ foreach (var item in _chassis.AnalogAuxiliaryMixer)
+ {
+ Debug.Console(2, this, "----> AnalogAuxillaryMixer[{0}].LineMuteVolumeControl.Count-{1}", item.MixerNumber, item.LineMuteVolumeControl.Count);
+ Debug.Console(2, this, "----> AnalogAuxillaryMixer[{0}].SourceMuteVolumeControl.Count-{1}", item.MixerNumber, item.SourceMuteVolumeControl.Count);
+ }
+ */
+ _chassis.DMOutputChange += _chassis_OutputChange;
+ }
+
+
+ public void ListRoutingPorts()
+ {
+ try
+ {
+ foreach (var port in InputPorts)
+ {
+ Debug.Console(0, this, @"Input Port Key: {0}
+Port: {1}
+Type: {2}
+ConnectionType: {3}
+Selector: {4}
+", port.Key, port.Port, port.Type, port.ConnectionType, port.Selector);
+ }
+
+ foreach (var port in OutputPorts)
+ {
+ Debug.Console(0, this, @"Port Port Key: {0}
+Port: {1}
+Type: {2}
+ConnectionType: {3}
+Selector: {4}
+", port.Key, port.Port, port.Type, port.ConnectionType, port.Selector);
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.Console(0, this, "ListRoutingPorts Exception Message: {0}", ex.Message);
+ Debug.Console(0, this, "ListRoutingPorts Exception StackTrace: {0}", ex.StackTrace);
+ if (ex.InnerException != null) Debug.Console(0, this, "ListRoutingPorts InnerException: {0}", ex.InnerException);
+ }
+ }
+
+ #region BridgeLinking
+
+ ///
+ /// Link device to API
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new HdPsXxxControllerJoinMap(joinStart);
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ else
+ {
+ Debug.Console(0, this, "Please update config to use 'eiscApiAdvanced' to get all join map features for this device");
+ }
+
+ IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
+ DeviceNameFeedback.LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
+
+ _chassis.OnlineStatusChange += _chassis_OnlineStatusChange;
+
+ LinkChassisInputsToApi(trilist, joinMap);
+ LinkChassisOutputsToApi(trilist, joinMap);
+
+ trilist.OnlineStatusChange += (sender, args) =>
+ {
+ if (!args.DeviceOnLine) return;
+ };
+ }
+
+
+ // links inputs to API
+ private void LinkChassisInputsToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap)
+ {
+ for (uint i = 1; i <= _chassis.NumberOfInputs; i++)
+ {
+ var input = i;
+ var inputName = InputNames[input];
+ var indexWithOffset = input - 1;
+
+ trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + indexWithOffset, () => EnableHdcp(input));
+ trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + indexWithOffset, () => DisableHdcp(input));
+
+ InputHdcpEnableFeedback[inputName].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + indexWithOffset]);
+ InputHdcpEnableFeedback[inputName].LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + indexWithOffset]);
+
+ VideoInputSyncFeedbacks[inputName].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + indexWithOffset]);
+
+ InputNameFeedbacks[inputName].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + indexWithOffset]);
+ }
+ }
+
+
+ // links outputs to API
+ private void LinkChassisOutputsToApi(BasicTriList trilist, HdPsXxxControllerJoinMap joinMap)
+ {
+ for (uint i = 1; i <= _chassis.NumberOfOutputs; i++)
+ {
+ var output = i;
+ var outputName = OutputNames[output];
+ var indexWithOffset = output - 1;
+
+ trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + indexWithOffset, (a) =>
+ ExecuteNumericSwitch(a, (ushort)output, eRoutingSignalType.AudioVideo));
+
+ OutputNameFeedbacks[outputName].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + indexWithOffset]);
+ OutputRouteNameFeedback[outputName].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + indexWithOffset]);
+
+ VideoOutputRouteFeedbacks[outputName].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + indexWithOffset]);
+ }
+
+ AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
+ }
+
+ #endregion
+
+
+ ///
+ /// Executes a device switch using objects
+ ///
+ ///
+ ///
+ ///
+ public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
+ {
+ var input = inputSelector as HdPsXxxInput;
+ var output = outputSelector as HdPsXxxOutput;
+
+ Debug.Console(2, this, "ExecuteSwitch: input={0}, output={1}", input, output);
+
+ if (output == null)
+ {
+ Debug.Console(0, this, "Unable to make switch, output selector is not HdPsXxxHdmiOutput");
+ return;
+ }
+
+ // TODO [ ] Validate if sending the same input toggles the switch
+ var current = output.VideoOut;
+ if (current != input)
+ output.VideoOut = input;
+ }
+
+
+ ///
+ /// Executes a device switch using numeric values
+ ///
+ ///
+ ///
+ ///
+ public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
+ {
+ var input = inputSelector == 0 ? null : _chassis.Inputs[inputSelector];
+ var output = _chassis.Outputs[outputSelector];
+
+ Debug.Console(2, this, "ExecuteNumericSwitch: input={0}, output={1}", input, output);
+
+ ExecuteSwitch(input, output, signalType);
+ }
+
+
+ ///
+ /// Enables Hdcp on the provided port
+ ///
+ ///
+ public void EnableHdcp(uint port)
+ {
+ if (port <= 0 || port > _chassis.NumberOfInputs) return;
+
+ _chassis.HdmiInputs[port].InputPort.HdcpSupportOn();
+ InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
+ }
+
+
+ ///
+ /// Disables Hdcp on the provided port
+ ///
+ ///
+ public void DisableHdcp(uint port)
+ {
+ if (port <= 0 || port > _chassis.NumberOfInputs) return;
+
+ _chassis.HdmiInputs[port].InputPort.HdcpSupportOff();
+ InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
+ }
+
+
+ ///
+ /// Enables switcher auto route
+ ///
+ public void EnableAutoRoute()
+ {
+ if (_chassis.NumberOfInputs == 1) return;
+
+ _chassis.AutoRouteOn();
+ }
+
+
+ ///
+ /// Disables switcher auto route
+ ///
+ public void DisableAutoRoute()
+ {
+ if (_chassis.NumberOfInputs == 1) return;
+
+ _chassis.AutoRouteOff();
+ }
+
+
+
+ #region Events
+
+
+ // _chassis online/offline event
+ private void _chassis_OnlineStatusChange(GenericBase currentDevice,
+ OnlineOfflineEventArgs args)
+ {
+ IsOnline.FireUpdate();
+
+ if (!args.DeviceOnLine) return;
+
+ foreach (var feedback in Feedbacks)
+ {
+ feedback.FireUpdate();
+ }
+ }
+
+
+ // _chassis input change event
+ private void _chassis_InputChange(Switch device, DMInputEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case DMInputEventIds.RemoteTransmitterDetectedEventId:
+ {
+ // signal found on HD-PSXxx > Inputs > Inputs DM Lite X
+ Debug.Console(2, this, "{0} DM Input Event ID {1}-RemoteTransmitterDetected | Number {2}",
+ device.ToString(), args.EventId, args.Number);
+ break;
+ }
+ case DMInputEventIds.SourceSyncEventId: // id-14
+ case DMInputEventIds.VideoDetectedEventId: // id-9
+ {
+ // signal found on HD-PSXxx > Inputs > HDMI/DM Lite X
+ Debug.Console(1, this, "{0} DM Input Event ID {1} | Number {2}: Updating VideoInputSyncFeedbacks",
+ device.Name, args.EventId, args.Number);
+
+ var input = args.Number;
+
+ var feedback = VideoInputSyncFeedbacks[(int)input];
+ if (feedback == null) return;
+
+ feedback.FireUpdate();
+
+ break;
+ }
+ case DMInputEventIds.InputNameFeedbackEventId:
+ case DMInputEventIds.InputNameEventId:
+ case DMInputEventIds.NameFeedbackEventId:
+ {
+ Debug.Console(1, this, "{0} DM Input Event ID {1}-Name | Number {2}: Updating name feedbacks",
+ device.Name, args.EventId, args.Number);
+
+ var input = args.Number;
+ var name = _chassis.HdmiInputs[input].NameFeedback.StringValue;
+
+ Debug.Console(1, this, "Input {0} Name {1}", input, name);
+ break;
+ }
+ default:
+ {
+ Debug.Console(1, this, "{0} DM Input Event ID {1} | Number {2}: Uhandled",
+ device.Name, args.EventId, args.Number);
+ break;
+ }
+ }
+
+ OnDmInputChange(args);
+ }
+
+ // _chassis output change event
+ private void _chassis_OutputChange(Switch device, DMOutputEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case DMOutputEventIds.VideoOutEventId:
+ {
+ Debug.Console(2, this, "{0} DM Output Event Id {1} | Number {2} | Index {3}: VideoOutEventId",
+ device.Name, args.EventId, args.Number, args.Index);
+
+ var output = args.Number;
+
+ var input = _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback == null
+ ? 0
+ : _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback.Number;
+
+ var outputName = OutputNames[output];
+
+ var feedback = VideoOutputRouteFeedbacks[outputName];
+ if (feedback == null) return;
+
+ var inputPort = InputPorts.FirstOrDefault(
+ p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output].VideoOutFeedback);
+
+ var outputPort = OutputPorts.FirstOrDefault(
+ p => p.FeedbackMatchObject == _chassis.HdmiDmLiteOutputs[output]);
+
+ feedback.FireUpdate();
+
+ OnSwitchChange(new RoutingNumericEventArgs(output, input, outputPort, inputPort, eRoutingSignalType.AudioVideo));
+
+ break;
+ }
+ case DMOutputEventIds.RemoteReceiverDetectedEventId:
+ {
+ // signal found on HD-PSXxx > Output[s] > Output [X] > DM Lite [X]
+ Debug.Console(2, this, "{0} DM Output Event Id {1} | Number {2} | Index {3}: RemoteRecevierDetectedEventId",
+ device.Name, args.EventId, args.Number, args.Index);
+ break;
+ }
+ default:
+ {
+ Debug.Console(2, this, "{0} DM Output Event Id {1} | Number {2} | Index:{3}: Unhandled",
+ device.Name, args.EventId, args.Number, args.Index);
+ break;
+ }
+ }
+ }
+
+
+ // Raise an event when the status of a switch object changes.
+ private void OnSwitchChange(RoutingNumericEventArgs args)
+ {
+ var newEvent = NumericSwitchChange;
+ if (newEvent != null) newEvent(this, args);
+ }
+
+ // Raise an event when the DM input changes.
+ private void OnDmInputChange(DMInputEventArgs args)
+ {
+ var newEvent = DmInputChange;
+ if (newEvent != null) newEvent(this, args);
+ }
+
+
+ #endregion
+
+
+
+ #region Factory
+
+
+ public class HdPsXxxControllerFactory : EssentialsDeviceFactory
+ {
+ public HdPsXxxControllerFactory()
+ {
+ TypeNames = new List { "hdps401", "hdps402", "hdps621", "hdps622" };
+ }
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ var key = dc.Key;
+ var name = dc.Name;
+ var type = dc.Type.ToLower();
+
+ Debug.Console(1, "Factory Attempting to create new {0} device", type);
+
+ var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
+ if (props == null)
+ {
+ Debug.Console(1, "Factory failed to create new HD-PSXxx device, properties config was null");
+ return null;
+ }
+
+ var ipid = props.Control.IpIdInt;
+
+ switch (type)
+ {
+ case ("hdps401"):
+ {
+ return new HdPsXxxController(key, name, new HdPs401(ipid, Global.ControlSystem), props);
+ }
+ case ("hdps402"):
+ {
+ return new HdPsXxxController(key, name, new HdPs402(ipid, Global.ControlSystem), props);
+ }
+ case ("hdps621"):
+ {
+ return new HdPsXxxController(key, name, new HdPs621(ipid, Global.ControlSystem), props);
+ }
+ case ("hdps622"):
+ {
+ return new HdPsXxxController(key, name, new HdPs622(ipid, Global.ControlSystem), props);
+ }
+ default:
+ {
+ Debug.Console(1, "Factory failed to create new {0} device", type);
+ return null;
+ }
+ }
+ }
+ }
+
+
+ #endregion
+ }
+
+
+ public class StreamCecWrapper : IKeyed, ICec
+ {
+ public string Key { get; private set; }
+ public Cec StreamCec { get; private set; }
+
+ public StreamCecWrapper(string key, Cec streamCec)
+ {
+ Key = key;
+ StreamCec = streamCec;
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs
new file mode 100644
index 00000000..57067bde
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Chassis/HdPsXxxOutputAudioController.cs
@@ -0,0 +1,167 @@
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DM;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash_Essentials_DM.Chassis
+{
+ public class HdPsXxxOutputAudioController : IKeyed,
+ IHasVolumeControlWithFeedback, IHasMuteControlWithFeedback
+ {
+ public string Key { get; private set; }
+
+ private readonly HdPsXxxHdmiDmLiteOutputMixer _mixer; // volume/volumeFeedback
+ private readonly HdPsXxxOutputPort _port; // mute/muteFeedback
+
+ public HdPsXxxOutputAudioController(string parent, uint output, HdPsXxx chassis)
+ {
+ Key = string.Format("{0}-audioOut{1}", parent, output);
+
+ _port = chassis.HdmiDmLiteOutputs[output].OutputPort;
+ _mixer = chassis.HdmiDmLiteOutputs[output].Mixer;
+
+ chassis.DMOutputChange += ChassisOnDmOutputChange;
+
+ VolumeLevelFeedback = new IntFeedback(() => VolumeLevel);
+ MuteFeedback = new BoolFeedback(() => IsMuted);
+ }
+
+ private void ChassisOnDmOutputChange(Switch device, DMOutputEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case (DMOutputEventIds.VolumeEventId):
+ {
+ Debug.Console(2, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - AudioMute/UnmuteEventId",
+ device.ToString(), args.Index, args.EventId, args.Number);
+
+ VolumeLevel = _mixer.VolumeFeedback.ShortValue;
+
+ break;
+ }
+ case DMOutputEventIds.MuteOnEventId:
+ case DMOutputEventIds.MuteOffEventId:
+ {
+ Debug.Console(2, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - MuteOnEventId/MuteOffEventId",
+ device.ToString(), args.Index, args.EventId, args.Number);
+
+ IsMuted = _port.MuteOnFeedback.BoolValue;
+
+ break;
+ }
+ default:
+ {
+ Debug.Console(1, this, "HdPsXxxOutputAudioController: {0} > Index-{1}, Number-{3}, EventId-{2} - unhandled eventId",
+ device.ToString(), args.Index, args.EventId, args.Number);
+ break;
+ }
+ }
+ }
+
+ #region Volume
+
+ private const ushort CrestronLevelMin = 0;
+ private const ushort CrestronLevelMax = 65535;
+
+ private const int DeviceLevelMin = -800;
+ private const int DeviceLevelMax = 200;
+
+ private const int RampTime = 5000;
+
+ private int _volumeLevel;
+
+ public int VolumeLevel
+ {
+ get { return _volumeLevel; }
+ private set
+ {
+ var level = value;
+
+ _volumeLevel = CrestronEnvironment.ScaleWithLimits(level, DeviceLevelMax, DeviceLevelMin, CrestronLevelMax, CrestronLevelMin);
+
+ Debug.Console(2, this, "VolumeFeedback: level-'{0}', scaled-'{1}'", level, _volumeLevel);
+
+ VolumeLevelFeedback.FireUpdate();
+ }
+ }
+
+ public IntFeedback VolumeLevelFeedback { get; private set; }
+
+ public void SetVolume(ushort level)
+ {
+ var levelScaled = CrestronEnvironment.ScaleWithLimits(level, CrestronLevelMax, CrestronLevelMin, DeviceLevelMax, DeviceLevelMin);
+
+ Debug.Console(1, this, "SetVolume: level-'{0}', levelScaled-'{1}'", level, levelScaled);
+
+ _mixer.Volume.ShortValue = (short)levelScaled;
+ }
+
+ public void VolumeUp(bool pressRelease)
+ {
+ if (pressRelease)
+ {
+ _mixer.Volume.CreateSignedRamp(DeviceLevelMax, RampTime);
+ }
+ else
+ {
+ _mixer.Volume.StopRamp();
+ }
+ }
+
+ public void VolumeDown(bool pressRelease)
+ {
+ if (pressRelease)
+ {
+ _mixer.Volume.CreateSignedRamp(DeviceLevelMin, RampTime);
+ }
+ else
+ {
+ _mixer.Volume.StopRamp();
+ }
+ }
+
+ #endregion
+
+
+
+
+ #region Mute
+
+ private bool _isMuted;
+
+ public bool IsMuted
+ {
+ get { return _isMuted; }
+ set
+ {
+ _isMuted = value;
+
+ Debug.Console(1, this, "IsMuted: _isMuted-'{0}'", _isMuted);
+
+ MuteFeedback.FireUpdate();
+ }
+ }
+
+ public BoolFeedback MuteFeedback { get; private set; }
+
+ public void MuteOn()
+ {
+ _port.MuteOn();
+ }
+
+ public void MuteOff()
+ {
+ _port.MuteOff();
+ }
+
+ public void MuteToggle()
+ {
+ if (IsMuted)
+ MuteOff();
+ else
+ MuteOn();
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs
new file mode 100644
index 00000000..f5eb9d39
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Config/HdPsXxxPropertiesConfig.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using PepperDash.Core;
+
+namespace PepperDash_Essentials_DM.Config
+{
+ public class HdPsXxxPropertiesConfig
+ {
+ [JsonProperty("control")]
+ public ControlPropertiesConfig Control { get; set; }
+
+ [JsonProperty("inputs")]
+ public Dictionary Inputs { get; set; }
+
+ [JsonProperty("outputs")]
+ public Dictionary Outputs { get; set; }
+
+ [JsonProperty("volumeMixerId")]
+ public uint VolumeMixerId { get; set; }
+
+ // "inputPriorities": "1,4,3,2"
+ [JsonProperty("inputPriorities")]
+ public string InputPriorities { get; set; }
+
+ public HdPsXxxPropertiesConfig()
+ {
+ Inputs = new Dictionary();
+ Outputs = new Dictionary();
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs
index ea220a13..6b0cdf28 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/Dge100Controller.cs
@@ -17,11 +17,12 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Config;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core.DeviceInfo;
+using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.DM.Endpoints.DGEs
{
[Description("Wrapper class for DGE-100")]
- public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec, IDeviceInfoProvider
+ public class Dge100Controller : CrestronGenericBaseDevice, IComPorts, IIROutputPorts, IHasBasicTriListWithSmartObject, ICec, IDeviceInfoProvider, IBridgeAdvanced
{
private const int CtpPort = 41795;
private readonly Dge100 _dge;
@@ -30,9 +31,12 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
public BasicTriListWithSmartObject Panel { get { return _dge; } }
- private DeviceConfig _dc;
+ private DeviceConfig _dc;
+
+ public VideoStatusOutputs VideoStatusFeedbacks { get; private set; }
+
+ CrestronTouchpanelPropertiesConfig PropertiesConfig;
- CrestronTouchpanelPropertiesConfig PropertiesConfig;
public Dge100Controller(string key, string name, Dge100 device, DeviceConfig dc, CrestronTouchpanelPropertiesConfig props)
:base(key, name, device)
@@ -48,8 +52,20 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
_dc = dc;
- PropertiesConfig = props;
- }
+ PropertiesConfig = props;
+
+ var videoStatusFuncs = new VideoStatusFuncsWrapper
+ {
+ HdcpActiveFeedbackFunc = () => _dge.HdmiIn.HdcpSupportOnFeedback.BoolValue,
+ VideoResolutionFeedbackFunc = () => _dge.HdmiIn.VideoAttributes.GetVideoResolutionString(),
+ VideoSyncFeedbackFunc = () => _dge.HdmiIn.SyncDetectedFeedback.BoolValue,
+ };
+
+ VideoStatusFeedbacks = new VideoStatusOutputs(videoStatusFuncs);
+
+ _dge.HdmiIn.StreamChange += (s,a) => VideoStatusFeedbacks.FireAll();
+ _dge.HdmiIn.VideoAttributes.AttributeChange += (o, a) => VideoStatusFeedbacks.FireAll();
+ }
#region IComPorts Members
@@ -187,6 +203,63 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
handler(this, new DeviceInfoEventArgs(DeviceInfo));
}
+ #endregion
+
+ #region IBridgeAdvanced Members
+
+ public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = new DgeJoinMap(joinStart);
+
+ var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
+
+ if (!string.IsNullOrEmpty(joinMapSerialized))
+ joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
+
+ if (bridge != null)
+ {
+ bridge.AddJoinMap(Key, joinMap);
+ }
+ else
+ {
+ Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
+ }
+
+ Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+
+ //Presses
+ trilist.SetSigTrueAction(joinMap.HdmiInHdcpOn.JoinNumber, () => _dge.HdmiIn.HdcpSupportOn());
+ trilist.SetSigTrueAction(joinMap.HdmiInHdcpOff.JoinNumber,() => _dge.HdmiIn.HdcpSupportOff());
+ trilist.SetSigTrueAction(joinMap.HdmiInHdcpToggle.JoinNumber, () => {
+ if(_dge.HdmiIn.HdcpSupportOnFeedback.BoolValue)
+ {
+ _dge.HdmiIn.HdcpSupportOff();
+ return;
+ }
+
+ _dge.HdmiIn.HdcpSupportOn();
+ });
+
+
+ // Feedbacks
+ VideoStatusFeedbacks.HdcpActiveFeedback.LinkInputSig(trilist.BooleanInput[joinMap.HdmiInHdcpOn.JoinNumber]);
+ VideoStatusFeedbacks.HdcpActiveFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.HdmiInHdcpOff.JoinNumber]);
+
+ VideoStatusFeedbacks.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentInputResolution.JoinNumber]);
+ VideoStatusFeedbacks.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SyncDetected.JoinNumber]);
+
+ IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
+
+ trilist.OnlineStatusChange += (o, a) =>
+ {
+ if (!a.DeviceOnLine) return;
+
+ VideoStatusFeedbacks.FireAll();
+ };
+ }
+
+
+
#endregion
}
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeJoinMap.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeJoinMap.cs
new file mode 100644
index 00000000..f53e9383
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DgeJoinMap.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash.Essentials.DM.Endpoints.DGEs
+{
+ public class DgeJoinMap : JoinMapBaseAdvanced
+ {
+ [JoinName("IsOnline")]
+ public JoinDataComplete IsOnline = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "DGE Online", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("CurrentInputResolution")]
+ public JoinDataComplete CurrentInputResolution = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
+ new JoinMetadata { Description = "DGE Current Input Resolution", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
+
+ [JoinName("SyncDetected")]
+ public JoinDataComplete SyncDetected = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
+ new JoinMetadata { Description = "DGE Sync Detected", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("HdmiHdcpOn")]
+ public JoinDataComplete HdmiInHdcpOn = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
+ new JoinMetadata { Description = "DGE HDMI HDCP State On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("HdmiHdcpOff")]
+ public JoinDataComplete HdmiInHdcpOff = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
+ new JoinMetadata { Description = "DGE HDMI HDCP State Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
+
+ [JoinName("HdmiHdcpToggle")]
+ public JoinDataComplete HdmiInHdcpToggle = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
+ new JoinMetadata { Description = "DGE HDMI HDCP State Toggle", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
+
+ public DgeJoinMap(uint joinStart)
+ : this(joinStart, typeof(DgeJoinMap))
+ {
+ }
+
+ ///
+ /// Constructor to use when extending this Join map
+ ///
+ /// Join this join map will start at
+ /// Type of the child join map
+ protected DgeJoinMap(uint joinStart, Type type) : base(joinStart, type)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DmDge200CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DmDge200CController.cs
index 31da45b2..d5df7dc6 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DmDge200CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/DGEs/DmDge200CController.cs
@@ -58,37 +58,37 @@ namespace PepperDash.Essentials.DM.Endpoints.DGEs
HdmiOut.Port = _dge.HdmiOut; ;
}
-
- public class DmDge200CControllerFactory : EssentialsDeviceFactory
- {
- public DmDge200CControllerFactory()
- {
- TypeNames = new List() { "dmdge200c" };
- }
-
- public override EssentialsDevice BuildDevice(DeviceConfig dc)
- {
- var typeName = dc.Type.ToLower();
- var comm = CommFactory.GetControlPropertiesConfig(dc);
- var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
-
- Debug.Console(1, "Factory Attempting to create new DgeController Device");
-
- DmDge200C dgeDevice = null;
-
- if (typeName == "dmdge200c")
- dgeDevice = new DmDge200C(comm.IpIdInt, Global.ControlSystem);
-
- if (dgeDevice == null)
- {
- Debug.Console(1, "Unable to create DGE device");
- return null;
- }
-
- var dgeController = new DmDge200CController(dc.Key , dc.Name, dgeDevice, dc, props);
-
- return dgeController;
- }
- }
}
+
+ public class DmDge200CControllerFactory : EssentialsDeviceFactory
+ {
+ public DmDge200CControllerFactory()
+ {
+ TypeNames = new List() { "dmdge200c" };
+ }
+
+ public override EssentialsDevice BuildDevice(DeviceConfig dc)
+ {
+ var typeName = dc.Type.ToLower();
+ var comm = CommFactory.GetControlPropertiesConfig(dc);
+ var props = JsonConvert.DeserializeObject(dc.Properties.ToString());
+
+ Debug.Console(1, "Factory Attempting to create new DgeController Device");
+
+ DmDge200C dgeDevice = null;
+
+ if (typeName == "dmdge200c")
+ dgeDevice = new DmDge200C(comm.IpIdInt, Global.ControlSystem);
+
+ if (dgeDevice == null)
+ {
+ Debug.Console(1, "Unable to create DGE device");
+ return null;
+ }
+
+ var dgeController = new DmDge200CController(dc.Key, dc.Name, dgeDevice, dc, props);
+
+ return dgeController;
+ }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/EndpointInterfaces.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/EndpointInterfaces.cs
new file mode 100644
index 00000000..e7df4547
--- /dev/null
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/EndpointInterfaces.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using PepperDash.Essentials.Core;
+
+namespace PepperDash_Essentials_DM
+{
+ public interface IHasDmInHdcpSet
+ {
+ void SetDmInHdcpState(eHdcpCapabilityType hdcpState);
+ }
+
+ public interface IHasDmInHdcpGet
+ {
+ IntFeedback DmInHdcpStateFeedback { get; }
+ }
+
+ public interface IHasDmInHdcp : IHasDmInHdcpGet, IHasDmInHdcpSet
+ {
+ eHdcpCapabilityType DmInHdcpCapability { get; }
+ }
+
+
+ public interface IHasHdmiInHdcpSet
+ {
+ void SetHdmiInHdcpState(eHdcpCapabilityType hdcpState);
+ }
+
+ public interface IHasHdmiInHdcpGet
+ {
+ IntFeedback HdmiInHdcpStateFeedback { get; }
+ }
+
+ public interface IHasHdmiInHdcp : IHasHdmiInHdcpGet, IHasHdmiInHdcpSet
+ {
+ eHdcpCapabilityType HdmiInHdcpCapability { get; }
+ }
+
+
+ public interface IHasHdmiIn1HdcpSet
+ {
+ void SetHdmiIn1HdcpState(eHdcpCapabilityType hdcpState);
+ }
+
+ public interface IHasHdmiIn1HdcpGet
+ {
+ IntFeedback HdmiIn1HdcpStateFeedback { get; }
+ }
+
+ public interface IHasHdmiIn1Hdcp : IHasHdmiIn1HdcpGet, IHasHdmiIn1HdcpSet
+ {
+ eHdcpCapabilityType HdmiIn1HdcpCapability { get; }
+ }
+
+
+ public interface IHasHdmiIn2HdcpSet
+ {
+ void SetHdmiIn2HdcpState(eHdcpCapabilityType hdcpState);
+ }
+
+ public interface IHasHdmiIn2HdcpGet
+ {
+ IntFeedback HdmiInIn2HdcpStateFeedback { get; }
+ }
+
+ public interface IHasHdmi2InHdcp : IHasHdmiIn2HdcpGet, IHasHdmiIn2HdcpSet
+ {
+ eHdcpCapabilityType Hdmi2InHdcpCapability { get; }
+ }
+
+
+
+ public interface IHasDisplayPortInHdcpGet
+ {
+ IntFeedback DisplayPortInHdcpStateFeedback { get; }
+ }
+
+ public interface IHasDisplayPortInHdcpSet
+ {
+ void SetDisplayPortInHdcpState(eHdcpCapabilityType hdcpState);
+ }
+
+ public interface IHasDisplayPortInHdcp : IHasDisplayPortInHdcpGet, IHasDisplayPortInHdcpSet
+ {
+ eHdcpCapabilityType DisplayPortInHdcpCapability { get; }
+ }
+
+ public interface IhasWallMode
+ {
+ void SetWallMode(ushort walLMode);
+ }
+
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmHdBaseTEndpointController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmHdBaseTEndpointController.cs
index ec3553a1..bfea158e 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmHdBaseTEndpointController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmHdBaseTEndpointController.cs
@@ -28,6 +28,8 @@ namespace PepperDash.Essentials.DM
InputPorts = new RoutingPortCollection {DmIn};
OutputPorts = new RoutingPortCollection {HDBaseTSink};
+ PreventRegistration = true;
+ rmc.Register();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs
index f33dd5be..0753ed4a 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc150SController.cs
@@ -1,99 +1,99 @@
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
-
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.DM
-{
- ///
- /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
- ///
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
+
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.DM
+{
+ ///
+ /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
+ ///
///
- [Description("Wrapper Class for DM-RMC-150-S")]
- public class DmRmc150SController : DmRmcControllerBase, IRoutingInputsOutputs,
- IIROutputPorts, IComPorts, ICec
- {
- private readonly DmRmc150S _rmc;
-
- public RoutingInputPort DmIn { get; private set; }
- public RoutingOutputPort HdmiOut { get; private set; }
-
- public RoutingPortCollection InputPorts
- {
- get; private set;
- }
-
- public RoutingPortCollection OutputPorts
- {
- get;
- private set ;
- }
-
- ///
- /// Make a Crestron RMC and put it in here
- ///
- public DmRmc150SController(string key, string name, DmRmc150S rmc)
- : base(key, name, rmc)
- {
- _rmc = rmc;
- DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.DmCat, 0, this);
- HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.Hdmi, null, this);
-
- EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
- EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
- EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
- EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
-
- InputPorts = new RoutingPortCollection {DmIn};
- OutputPorts = new RoutingPortCollection {HdmiOut};
-
- _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
-
- // Set Ports for CEC
- HdmiOut.Port = _rmc.HdmiOutput;
- }
-
- void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
- {
- switch (args.EventId)
- {
- case ConnectedDeviceEventIds.ManufacturerEventId:
- EdidManufacturerFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.NameEventId:
- EdidNameFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.PreferredTimingEventId:
- EdidPreferredTimingFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.SerialNumberEventId:
- EdidSerialNumberFeedback.FireUpdate();
- break;
- }
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge);
- }
-
- #region IIROutputPorts Members
- public CrestronCollection IROutputPorts { get { return _rmc.IROutputPorts; } }
- public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }
- #endregion
-
- #region IComPorts Members
- public CrestronCollection ComPorts { get { return _rmc.ComPorts; } }
- public int NumberOfComPorts { get { return _rmc.NumberOfComPorts; } }
- #endregion
-
- #region ICec Members
- public Cec StreamCec { get { return _rmc.HdmiOutput.StreamCec; } }
- #endregion
- }
+ [Description("Wrapper Class for DM-RMC-150-S")]
+ public class DmRmc150SController : DmRmcControllerBase, IRoutingInputsOutputs,
+ IIROutputPorts, IComPorts, ICec
+ {
+ private readonly DmRmc150S _rmc;
+
+ public RoutingInputPort DmIn { get; private set; }
+ public RoutingOutputPort HdmiOut { get; private set; }
+
+ public RoutingPortCollection InputPorts
+ {
+ get; private set;
+ }
+
+ public RoutingPortCollection OutputPorts
+ {
+ get;
+ private set ;
+ }
+
+ ///
+ /// Make a Crestron RMC and put it in here
+ ///
+ public DmRmc150SController(string key, string name, DmRmc150S rmc)
+ : base(key, name, rmc)
+ {
+ _rmc = rmc;
+ DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.DmCat, 0, this);
+ HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.Hdmi, null, this);
+
+ EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
+ EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
+ EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
+ EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
+
+ InputPorts = new RoutingPortCollection {DmIn};
+ OutputPorts = new RoutingPortCollection {HdmiOut};
+
+ _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
+
+ // Set Ports for CEC
+ HdmiOut.Port = _rmc.HdmiOutput;
+ }
+
+ void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case ConnectedDeviceEventIds.ManufacturerEventId:
+ EdidManufacturerFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.NameEventId:
+ EdidNameFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.PreferredTimingEventId:
+ EdidPreferredTimingFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.SerialNumberEventId:
+ EdidSerialNumberFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge);
+ }
+
+ #region IIROutputPorts Members
+ public CrestronCollection IROutputPorts { get { return _rmc.IROutputPorts; } }
+ public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }
+ #endregion
+
+ #region IComPorts Members
+ public CrestronCollection ComPorts { get { return _rmc.ComPorts; } }
+ public int NumberOfComPorts { get { return _rmc.NumberOfComPorts; } }
+ #endregion
+
+ #region ICec Members
+ public Cec StreamCec { get { return _rmc.HdmiOutput.StreamCec; } }
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs
index ed5bd378..df39e4ee 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc200CController.cs
@@ -1,111 +1,111 @@
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
-
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.DM
-{
- ///
- /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
- ///
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
+
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.DM
+{
+ ///
+ /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
+ ///
///
[Description("Wrapper Class for DM-RMC-200-C")]
- public class DmRmc200CController : DmRmcControllerBase, IRoutingInputsOutputs,
- IIROutputPorts, IComPorts, ICec
- {
- private readonly DmRmc200C _rmc;
-
- public RoutingInputPort DmIn { get; private set; }
+ public class DmRmc200CController : DmRmcControllerBase, IRoutingInputsOutputs,
+ IIROutputPorts, IComPorts, ICec
+ {
+ private readonly DmRmc200C _rmc;
+
+ public RoutingInputPort DmIn { get; private set; }
public RoutingOutputPort HdmiOut { get; private set; }
-
- public RoutingPortCollection InputPorts
- {
- get; private set;
- }
-
- public RoutingPortCollection OutputPorts
- {
- get; private set;
- }
-
- ///
- /// Make a Crestron RMC and put it in here
- ///
- public DmRmc200CController(string key, string name, DmRmc200C rmc)
- : base(key, name, rmc)
- {
- _rmc = rmc;
- DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.DmCat, 0, this);
- HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.Hdmi, null, this);
-
- EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
- EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
- EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
- EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
-
- VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
-
- _rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
- _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
-
- InputPorts = new RoutingPortCollection {DmIn};
- OutputPorts = new RoutingPortCollection {HdmiOut};
-
- // Set Ports for CEC
- HdmiOut.Port = _rmc.HdmiOutput;
- }
-
- void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args)
- {
- if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId ||
- args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId)
- {
- VideoOutputResolutionFeedback.FireUpdate();
- }
- }
-
- void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
- {
- switch (args.EventId)
- {
- case ConnectedDeviceEventIds.ManufacturerEventId:
- EdidManufacturerFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.NameEventId:
- EdidNameFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.PreferredTimingEventId:
- EdidPreferredTimingFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.SerialNumberEventId:
- EdidSerialNumberFeedback.FireUpdate();
- break;
- }
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge);
- }
-
- #region IIROutputPorts Members
- public CrestronCollection IROutputPorts { get { return _rmc.IROutputPorts; } }
- public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }
- #endregion
-
- #region IComPorts Members
- public CrestronCollection ComPorts { get { return _rmc.ComPorts; } }
- public int NumberOfComPorts { get { return _rmc.NumberOfComPorts; } }
- #endregion
-
- #region ICec Members
- public Cec StreamCec { get { return _rmc.HdmiOutput.StreamCec; } }
- #endregion
- }
+
+ public RoutingPortCollection InputPorts
+ {
+ get; private set;
+ }
+
+ public RoutingPortCollection OutputPorts
+ {
+ get; private set;
+ }
+
+ ///
+ /// Make a Crestron RMC and put it in here
+ ///
+ public DmRmc200CController(string key, string name, DmRmc200C rmc)
+ : base(key, name, rmc)
+ {
+ _rmc = rmc;
+ DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.DmCat, 0, this);
+ HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.Hdmi, null, this);
+
+ EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
+ EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
+ EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
+ EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
+
+ VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
+
+ _rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
+ _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
+
+ InputPorts = new RoutingPortCollection {DmIn};
+ OutputPorts = new RoutingPortCollection {HdmiOut};
+
+ // Set Ports for CEC
+ HdmiOut.Port = _rmc.HdmiOutput;
+ }
+
+ void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args)
+ {
+ if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId ||
+ args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId)
+ {
+ VideoOutputResolutionFeedback.FireUpdate();
+ }
+ }
+
+ void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case ConnectedDeviceEventIds.ManufacturerEventId:
+ EdidManufacturerFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.NameEventId:
+ EdidNameFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.PreferredTimingEventId:
+ EdidPreferredTimingFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.SerialNumberEventId:
+ EdidSerialNumberFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge);
+ }
+
+ #region IIROutputPorts Members
+ public CrestronCollection IROutputPorts { get { return _rmc.IROutputPorts; } }
+ public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }
+ #endregion
+
+ #region IComPorts Members
+ public CrestronCollection ComPorts { get { return _rmc.ComPorts; } }
+ public int NumberOfComPorts { get { return _rmc.NumberOfComPorts; } }
+ #endregion
+
+ #region ICec Members
+ public Cec StreamCec { get { return _rmc.HdmiOutput.StreamCec; } }
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs
index 052f0726..79debd63 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4KScalerCController.cs
@@ -1,196 +1,261 @@
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.DM
-{
- ///
- /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
- ///
- ///
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash_Essentials_DM;
+using System.Collections.Generic;
+
+namespace PepperDash.Essentials.DM
+{
+ ///
+ /// Builds a controller for basic DM-RMCs with Com and IR ports and no control functions
+ ///
+ ///
[Description("Wrapper Class for DM-RMC-4K-SCALER-C")]
- public class DmRmc4kScalerCController : DmRmcControllerBase, IRoutingInputsOutputs, IBasicVolumeWithFeedback,
- IIROutputPorts, IComPorts, ICec, IRelayPorts
- {
- private readonly DmRmc4kScalerC _rmc;
-
- public RoutingInputPort DmIn { get; private set; }
- public RoutingOutputPort HdmiOut { get; private set; }
- public RoutingOutputPort BalancedAudioOut { get; private set; }
-
- public RoutingPortCollection InputPorts { get; private set; }
-
- public RoutingPortCollection OutputPorts { get; private set; }
-
- ///
- /// Make a Crestron RMC and put it in here
- ///
- public DmRmc4kScalerCController(string key, string name, DmRmc4kScalerC rmc)
- : base(key, name, rmc)
- {
- _rmc = rmc;
-
- DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.DmCat, 0, this);
- HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
- eRoutingPortConnectionType.Hdmi, null, this);
- BalancedAudioOut = new RoutingOutputPort(DmPortName.BalancedAudioOut, eRoutingSignalType.Audio,
- eRoutingPortConnectionType.LineAudio, null, this);
-
- MuteFeedback = new BoolFeedback(() => false);
-
- VolumeLevelFeedback = new IntFeedback("MainVolumeLevelFeedback", () =>
- rmc.AudioOutput.VolumeFeedback.UShortValue);
-
- EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
- EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
- EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
- EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
-
- InputPorts = new RoutingPortCollection {DmIn};
- OutputPorts = new RoutingPortCollection {HdmiOut, BalancedAudioOut};
-
- VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
-
- _rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
- _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
-
- // Set Ports for CEC
- HdmiOut.Port = _rmc.HdmiOutput;
- }
-
- void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args)
- {
- if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId ||
- args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId)
- {
- VideoOutputResolutionFeedback.FireUpdate();
- }
- }
-
- void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
- {
- switch (args.EventId)
- {
- case ConnectedDeviceEventIds.ManufacturerEventId:
- EdidManufacturerFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.NameEventId:
- EdidNameFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.PreferredTimingEventId:
- EdidPreferredTimingFeedback.FireUpdate();
- break;
- case ConnectedDeviceEventIds.SerialNumberEventId:
- EdidSerialNumberFeedback.FireUpdate();
- break;
- }
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge);
- }
-
- #region IIROutputPorts Members
- public CrestronCollection IROutputPorts { get { return _rmc.IROutputPorts; } }
- public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }
- #endregion
-
- #region IComPorts Members
- public CrestronCollection ComPorts { get { return _rmc.ComPorts; } }
- public int NumberOfComPorts { get { return _rmc.NumberOfComPorts; } }
- #endregion
-
- #region ICec Members
- ///
- /// Gets the CEC stream directly from the HDMI port.
- ///
- public Cec StreamCec { get { return _rmc.HdmiOutput.StreamCec; } }
- #endregion
-
- #region IRelayPorts Members
-
- public int NumberOfRelayPorts
- {
- get { return _rmc.NumberOfRelayPorts; }
- }
-
- public CrestronCollection RelayPorts
- {
- get { return _rmc.RelayPorts; }
- }
-
- #endregion
-
- #region IBasicVolumeWithFeedback Members
-
- public BoolFeedback MuteFeedback
- {
- get;
- private set;
- }
-
- ///
- /// Not implemented
- ///
- public void MuteOff()
- {
- Debug.Console(2, this, "DM Endpoint {0} does not have a mute function", Key);
- }
-
- ///
- /// Not implemented
- ///
- public void MuteOn()
- {
- Debug.Console(2, this, "DM Endpoint {0} does not have a mute function", Key);
- }
-
- public void SetVolume(ushort level)
- {
- _rmc.AudioOutput.Volume.UShortValue = level;
- }
-
- public IntFeedback VolumeLevelFeedback
- {
- get;
- private set;
- }
-
- #endregion
-
- #region IBasicVolumeControls Members
-
- ///
- /// Not implemented
- ///
- public void MuteToggle()
- {
- Debug.Console(2, this, "DM Endpoint {0} does not have a mute function", Key);
- }
-
- public void VolumeDown(bool pressRelease)
- {
- if (pressRelease)
- SigHelper.RampTimeScaled(_rmc.AudioOutput.Volume, 0, 4000);
- else
- _rmc.AudioOutput.Volume.StopRamp();
- }
-
- public void VolumeUp(bool pressRelease)
- {
- if (pressRelease)
- SigHelper.RampTimeScaled(_rmc.AudioOutput.Volume, 65535, 4000);
- else
- _rmc.AudioOutput.Volume.StopRamp();
- }
-
- #endregion
- }
+ public class DmRmc4kScalerCController : DmRmcControllerBase, IRoutingInputsOutputs, IBasicVolumeWithFeedback,
+ IIROutputPorts, IComPorts, ICec, IRelayPorts, IHasDmInHdcp, IBasicVideoMuteWithFeedback
+ {
+ private readonly DmRmc4kScalerC _rmc;
+
+ public RoutingInputPort DmIn { get; private set; }
+ public RoutingOutputPort HdmiOut { get; private set; }
+ public RoutingOutputPort BalancedAudioOut { get; private set; }
+
+ public RoutingPortCollection InputPorts { get; private set; }
+
+ public RoutingPortCollection OutputPorts { get; private set; }
+
+ public EndpointDmInputStreamWithCec DmInput { get; private set; }
+
+ public IntFeedback DmInHdcpStateFeedback { get; private set; }
+
+
+
+ ///
+ /// Make a Crestron RMC and put it in here
+ ///
+ public DmRmc4kScalerCController(string key, string name, DmRmc4kScalerC rmc)
+ : base(key, name, rmc)
+ {
+ _rmc = rmc;
+
+ DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.DmCat, 0, this);
+ HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
+ eRoutingPortConnectionType.Hdmi, null, this);
+ BalancedAudioOut = new RoutingOutputPort(DmPortName.BalancedAudioOut, eRoutingSignalType.Audio,
+ eRoutingPortConnectionType.LineAudio, null, this);
+
+ MuteFeedback = new BoolFeedback(() => false);
+
+ VolumeLevelFeedback = new IntFeedback("MainVolumeLevelFeedback", () =>
+ rmc.AudioOutput.VolumeFeedback.UShortValue);
+
+ EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
+ EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
+ EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
+ EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
+
+ InputPorts = new RoutingPortCollection { DmIn };
+ OutputPorts = new RoutingPortCollection { HdmiOut, BalancedAudioOut };
+
+ VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
+ DmInHdcpStateFeedback = new IntFeedback("DmInHdcpCapability",
+ () => (int)_rmc.DmInput.HdcpCapabilityFeedback);
+
+ AddToFeedbackList(DmInHdcpStateFeedback);
+
+ VideoMuteIsOn = new BoolFeedback("HdmiOutputVideoMuteIsOn", () => _rmc.HdmiOutput.BlankEnabledFeedback.BoolValue);
+
+ _rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
+ _rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
+
+ // Set Ports for CEC
+ HdmiOut.Port = _rmc.HdmiOutput;
+ }
+
+ void HdmiOutput_OutputStreamChange(EndpointOutputStream outputStream, EndpointOutputStreamEventArgs args)
+ {
+ if (args.EventId == EndpointOutputStreamEventIds.HorizontalResolutionFeedbackEventId || args.EventId == EndpointOutputStreamEventIds.VerticalResolutionFeedbackEventId ||
+ args.EventId == EndpointOutputStreamEventIds.FramesPerSecondFeedbackEventId)
+ {
+ VideoOutputResolutionFeedback.FireUpdate();
+ }
+ else if (args.EventId == EndpointOutputStreamEventIds.BlankEnabledFeedbackEventId)
+ {
+ VideoMuteIsOn.FireUpdate();
+ }
+ }
+
+ void ConnectedDevice_DeviceInformationChange(ConnectedDeviceInformation connectedDevice, ConnectedDeviceEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case ConnectedDeviceEventIds.ManufacturerEventId:
+ EdidManufacturerFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.NameEventId:
+ EdidNameFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.PreferredTimingEventId:
+ EdidPreferredTimingFeedback.FireUpdate();
+ break;
+ case ConnectedDeviceEventIds.SerialNumberEventId:
+ EdidSerialNumberFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ LinkDmRmcToApi(this, trilist, joinStart, joinMapKey, bridge);
+ }
+
+ #region IIROutputPorts Members
+ public CrestronCollection IROutputPorts { get { return _rmc.IROutputPorts; } }
+ public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }
+ #endregion
+
+ #region IComPorts Members
+ public CrestronCollection ComPorts { get { return _rmc.ComPorts; } }
+ public int NumberOfComPorts { get { return _rmc.NumberOfComPorts; } }
+ #endregion
+
+ #region ICec Members
+ ///
+ /// Gets the CEC stream directly from the HDMI port.
+ ///
+ public Cec StreamCec { get { return _rmc.HdmiOutput.StreamCec; } }
+ #endregion
+
+ #region IRelayPorts Members
+
+ public int NumberOfRelayPorts
+ {
+ get { return _rmc.NumberOfRelayPorts; }
+ }
+
+ public CrestronCollection RelayPorts
+ {
+ get { return _rmc.RelayPorts; }
+ }
+
+ #endregion
+
+ #region IBasicVolumeWithFeedback Members
+
+ public BoolFeedback MuteFeedback
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Not implemented
+ ///
+ public void MuteOff()
+ {
+ Debug.Console(2, this, "DM Endpoint {0} does not have a mute function", Key);
+ }
+
+ ///
+ /// Not implemented
+ ///
+ public void MuteOn()
+ {
+ Debug.Console(2, this, "DM Endpoint {0} does not have a mute function", Key);
+ }
+
+ public void SetVolume(ushort level)
+ {
+ _rmc.AudioOutput.Volume.UShortValue = level;
+ }
+
+ public IntFeedback VolumeLevelFeedback
+ {
+ get;
+ private set;
+ }
+
+ #endregion
+
+ #region IBasicVolumeControls Members
+
+ ///
+ /// Not implemented
+ ///
+ public void MuteToggle()
+ {
+ Debug.Console(2, this, "DM Endpoint {0} does not have a mute function", Key);
+ }
+
+ public void VolumeDown(bool pressRelease)
+ {
+ if (pressRelease)
+ SigHelper.RampTimeScaled(_rmc.AudioOutput.Volume, 0, 4000);
+ else
+ _rmc.AudioOutput.Volume.StopRamp();
+ }
+
+ public void VolumeUp(bool pressRelease)
+ {
+ if (pressRelease)
+ SigHelper.RampTimeScaled(_rmc.AudioOutput.Volume, 65535, 4000);
+ else
+ _rmc.AudioOutput.Volume.StopRamp();
+ }
+
+ #endregion
+
+ public eHdcpCapabilityType DmInHdcpCapability
+ {
+ get { return eHdcpCapabilityType.Hdcp2_2Support; }
+ }
+
+ public void SetDmInHdcpState(eHdcpCapabilityType hdcpState)
+ {
+ if (_rmc == null) return;
+ _rmc.DmInput.HdcpCapability = hdcpState;
+ }
+
+
+ #region IBasicVideoMuteWithFeedback Members
+
+ public BoolFeedback VideoMuteIsOn
+ {
+ get;
+ private set;
+ }
+
+ public void VideoMuteOn()
+ {
+ Debug.Console(2, this, "Video Mute On");
+ _rmc.HdmiOutput.BlankEnabled();
+ }
+
+ public void VideoMuteOff()
+ {
+ Debug.Console(2, this, "Video Mute Off");
+ _rmc.HdmiOutput.BlankDisabled();
+ }
+
+ #endregion
+
+ #region IBasicVideoMute Members
+
+ public void VideoMuteToggle()
+ {
+ Debug.Console(2, this, "Video Mute Toggle");
+ if (_rmc.HdmiOutput.BlankEnabledFeedback.BoolValue == true)
+ VideoMuteOff();
+ else
+ VideoMuteOn();
+ }
+
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4k100C1GController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4k100C1GController.cs
index 529f740a..d92d9620 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4k100C1GController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4k100C1GController.cs
@@ -32,7 +32,9 @@ namespace PepperDash.Essentials.DM
eRoutingPortConnectionType.Hdmi, null, this) {Port = _rmc};
InputPorts = new RoutingPortCollection {DmIn};
- OutputPorts = new RoutingPortCollection {HdmiOut};
+ OutputPorts = new RoutingPortCollection {HdmiOut};
+ PreventRegistration = true;
+ rmc.Register();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs
index a7c83e35..99bc35fd 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kScalerCDspController.cs
@@ -5,8 +5,9 @@ using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using PepperDash.Core;
using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash_Essentials_DM;
+
namespace PepperDash.Essentials.DM
{
///
@@ -15,7 +16,7 @@ namespace PepperDash.Essentials.DM
///
[Description("Wrapper Class for DM-RMC-4K-SCALER-C-DSP")]
public class DmRmc4kScalerCDspController : DmRmcControllerBase, IRoutingInputsOutputs, IBasicVolumeWithFeedback,
- IIROutputPorts, IComPorts, ICec, IRelayPorts
+ IIROutputPorts, IComPorts, ICec, IRelayPorts, IHasDmInHdcp
{
private readonly DmRmc4kScalerCDsp _rmc;
@@ -25,7 +26,12 @@ namespace PepperDash.Essentials.DM
public RoutingPortCollection InputPorts { get; private set; }
- public RoutingPortCollection OutputPorts { get; private set; }
+ public RoutingPortCollection OutputPorts { get; private set; }
+
+ public EndpointDmInputStreamWithCec DmInput { get; private set; }
+
+ public IntFeedback DmInHdcpStateFeedback { get; private set; }
+
///
/// Make a Crestron RMC and put it in here
@@ -51,7 +57,13 @@ namespace PepperDash.Essentials.DM
EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
EdidSerialNumberFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.SerialNumber.StringValue);
- VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
+ VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
+
+ DmInHdcpStateFeedback = new IntFeedback("DmInHdcpCapability",
+ () => (int) _rmc.DmInput.HdcpCapabilityFeedback);
+
+ AddToFeedbackList(DmInHdcpStateFeedback);
+
InputPorts = new RoutingPortCollection {DmIn};
OutputPorts = new RoutingPortCollection {HdmiOut, BalancedAudioOut};
@@ -190,6 +202,18 @@ namespace PepperDash.Essentials.DM
_rmc.AudioOutput.Volume.StopRamp();
}
- #endregion
+ #endregion
+
+ public eHdcpCapabilityType DmInHdcpCapability
+ {
+ get { return eHdcpCapabilityType.Hdcp2_2Support; }
+ }
+
+ public void SetDmInHdcpState(eHdcpCapabilityType hdcpState)
+ {
+ if (_rmc == null) return;
+ _rmc.DmInput.HdcpCapability = hdcpState;
+ }
+
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs
index 73dd59b9..afd9aff6 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmc4kZScalerCController.cs
@@ -9,12 +9,14 @@ using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Core;
+using PepperDash_Essentials_DM;
+using System.Collections.Generic;
namespace PepperDash.Essentials.DM
{
[Description("Wrapper Class for DM-RMC-4K-Z-SCALER-C")]
public class DmRmc4kZScalerCController : DmRmcControllerBase, IRmcRoutingWithFeedback,
- IIROutputPorts, IComPorts, ICec, IRelayPorts
+ IIROutputPorts, IComPorts, ICec, IRelayPorts, IHasDmInHdcp, IHasHdmiInHdcp, IhasWallMode
{
private readonly DmRmc4kzScalerC _rmc;
@@ -22,6 +24,14 @@ namespace PepperDash.Essentials.DM
public RoutingInputPort HdmiIn { get; private set; }
public RoutingOutputPort HdmiOut { get; private set; }
+ public IntFeedback DmInHdcpStateFeedback { get; private set; }
+ public IntFeedback HdmiInHdcpStateFeedback { get; private set; }
+
+
+ public BoolFeedback HdmiVideoSyncFeedback { get; private set; }
+
+ private Dictionary WallModes;
+
///
/// The value of the current video source for the HDMI output on the receiver
///
@@ -42,13 +52,13 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
- }
-
+ }
public DmRmc4kZScalerCController(string key, string name, DmRmc4kzScalerC rmc)
: base(key, name, rmc)
{
_rmc = rmc;
+
DmIn = new RoutingInputPort(DmPortName.DmIn, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.DmCat, 0, this)
{
@@ -62,6 +72,16 @@ namespace PepperDash.Essentials.DM
HdmiOut = new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, null, this);
+ HdmiInHdcpStateFeedback = new IntFeedback("HdmiInHdcpCapability",
+ () => (int)_rmc.HdmiIn.HdcpCapabilityFeedback);
+ DmInHdcpStateFeedback = new IntFeedback("DmInHdcpCapability",
+ () => (int)_rmc.DmInput.HdcpCapabilityFeedback);
+ HdmiVideoSyncFeedback = new BoolFeedback("HdmiInVideoSync",
+ () => _rmc.HdmiIn.SyncDetectedFeedback.BoolValue);
+
+ AddToFeedbackList(HdmiInHdcpStateFeedback, DmInHdcpStateFeedback, HdmiVideoSyncFeedback);
+
+
EdidManufacturerFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Manufacturer.StringValue);
EdidNameFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.Name.StringValue);
EdidPreferredTimingFeedback = new StringFeedback(() => _rmc.HdmiOutput.ConnectedDevice.PreferredTiming.StringValue);
@@ -69,11 +89,17 @@ namespace PepperDash.Essentials.DM
VideoOutputResolutionFeedback = new StringFeedback(() => _rmc.HdmiOutput.GetVideoResolutionString());
- InputPorts = new RoutingPortCollection {DmIn, HdmiIn};
- OutputPorts = new RoutingPortCollection {HdmiOut};
+ VideoWallModeRawFeedback = new IntFeedback("ScalerVideoWallModeRaw",
+ () => (int)_rmc.Scaler.WallModeRawFeedback.UShortValue);
+
+ InputPorts = new RoutingPortCollection { DmIn, HdmiIn };
+ OutputPorts = new RoutingPortCollection { HdmiOut };
_rmc.HdmiOutput.OutputStreamChange += HdmiOutput_OutputStreamChange;
_rmc.HdmiOutput.ConnectedDevice.DeviceInformationChange += ConnectedDevice_DeviceInformationChange;
+ _rmc.HdmiIn.InputStreamChange += InputStreamChangeEvent;
+ _rmc.DmInput.InputStreamChange += InputStreamChangeEvent;
+ _rmc.Scaler.OutputChange += Scaler_OutputChange;
_rmc.OnlineStatusChange += _rmc_OnlineStatusChange;
@@ -81,6 +107,29 @@ namespace PepperDash.Essentials.DM
HdmiOut.Port = _rmc.HdmiOutput;
AudioVideoSourceNumericFeedback = new IntFeedback(() => (ushort)(_rmc.SelectedSourceFeedback));
+
+ WallModes = new Dictionary()
+ {
+ {0, EndpointScalerOutput.eWall.Disabled},
+ {2211, EndpointScalerOutput.eWall.Mode11},
+ {2212, EndpointScalerOutput.eWall.Mode12},
+ {2221, EndpointScalerOutput.eWall.Mode13},
+ {2222, EndpointScalerOutput.eWall.Mode14}
+ };
+ }
+
+ void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
+ if (inputStream == _rmc.HdmiIn) HdmiInHdcpStateFeedback.FireUpdate();
+ if (inputStream == _rmc.DmInput) DmInHdcpStateFeedback.FireUpdate();
+ break;
+ case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
+ if (inputStream == _rmc.HdmiIn) HdmiVideoSyncFeedback.FireUpdate();
+ break;
+ }
}
private void _rmc_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
@@ -181,5 +230,73 @@ namespace PepperDash.Essentials.DM
}
#endregion
+
+
+ public eHdcpCapabilityType DmInHdcpCapability
+ {
+ get { return eHdcpCapabilityType.Hdcp2_2Support; }
+ }
+
+ public void SetDmInHdcpState(eHdcpCapabilityType hdcpState)
+ {
+
+ if (_rmc == null) return;
+ _rmc.DmInput.HdcpCapability = hdcpState;
+ }
+
+
+ public eHdcpCapabilityType HdmiInHdcpCapability
+ {
+ get { return eHdcpCapabilityType.Hdcp2_2Support; }
+ }
+
+ public void SetHdmiInHdcpState(eHdcpCapabilityType hdcpState)
+ {
+ if (_rmc == null) return;
+ _rmc.HdmiIn.HdcpCapability = hdcpState;
+ }
+
+
+ #region IhasWallMode Members
+
+ public void SetWallMode(ushort wallMode)
+ {
+ EndpointScalerOutput.eWall wallValue;
+
+ if (WallModes.TryGetValue(wallMode, out wallValue))
+ _rmc.Scaler.WallMode = wallValue;
+ }
+
+ #endregion
+
+ public void SetWallModeRaw(ushort wallMode)
+ {
+ _rmc.Scaler.WallModeRaw.UShortValue = wallMode;
+ }
+
+ void Scaler_OutputChange(EndpointScalerOutput scalerOutput, ScalerOutputEventArgs args)
+ {
+ if (scalerOutput == null)
+ {
+ Debug.Console(1, this, "Scaler Output object is null");
+ return;
+ }
+ if (args == null)
+ {
+ Debug.Console(1, this, "Scaler Output Args are null");
+ return;
+ }
+ Debug.Console(2, this, "Scaler Event ID: {0}", args.EventId);
+ switch (args.EventId)
+ {
+ case ScalerOutputEventIds.WallModeFeedbackEventId:
+ VideoWallModeRawFeedback.FireUpdate();
+ break;
+ default:
+ Debug.Console(2, this, "Scaler Default Unhandled Event ID: {0}", args.EventId);
+ break;
+ }
+ }
+
}
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs
index 5d644a2a..52d8a60e 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Cards;
@@ -11,11 +12,12 @@ using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.DeviceInfo;
using PepperDash.Essentials.DM.Config;
using PepperDash.Essentials.Core.Config;
+using PepperDash_Essentials_DM;
namespace PepperDash.Essentials.DM
{
[Description("Wrapper class for all DM-RMC variants")]
- public abstract class DmRmcControllerBase : CrestronGenericBridgeableBaseDevice, IDeviceInfoProvider
+ 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.
@@ -26,16 +28,19 @@ namespace PepperDash.Essentials.DM
public StringFeedback EdidPreferredTimingFeedback { get; protected set; }
public StringFeedback EdidSerialNumberFeedback { get; protected set; }
+ public IntFeedback VideoWallModeFeedback { get; protected set; }
+ public IntFeedback VideoWallModeRawFeedback { get; protected set; }
+
protected DmRmcControllerBase(string key, string name, EndpointReceiverBase device)
- : base(key, name, device)
+ : base(key, name, device)
{
_rmc = device;
- // if wired to a chassis, skip registration step in base class
+ // if wired to a chassis, skip registration step in base class
PreventRegistration = _rmc.DMOutput != null;
-
+
AddToFeedbackList(VideoOutputResolutionFeedback, EdidManufacturerFeedback, EdidSerialNumberFeedback, EdidNameFeedback, EdidPreferredTimingFeedback);
-
+
DeviceInfo = new DeviceInfo();
IsOnline.OutputChange += (currentDevice, args) => { if (args.BoolValue) UpdateDeviceInfo(); };
@@ -59,6 +64,11 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
+ LinkDmRmcToApi(rmc, trilist, joinMap);
+ }
+
+ protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, DmRmcControllerJoinMap joinMap)
+ {
Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
@@ -73,21 +83,110 @@ namespace PepperDash.Essentials.DM
rmc.EdidPreferredTimingFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidPrefferedTiming.JoinNumber]);
if (rmc.EdidSerialNumberFeedback != null)
rmc.EdidSerialNumberFeedback.LinkInputSig(trilist.StringInput[joinMap.EdidSerialNumber.JoinNumber]);
-
+
+
//If the device is an DM-RMC-4K-Z-SCALER-C
- var routing = rmc as IRmcRouting;
+ var routing = rmc as IRoutingInputsOutputs;
+
+ trilist.UShortInput[joinMap.HdcpInputPortCount.JoinNumber].UShortValue = (ushort)(routing == null
+ ? 1
+ : routing.InputPorts.Count);
if (routing == null)
{
return;
}
+ var hdcpCapability = eHdcpCapabilityType.HdcpSupportOff;
+ if (routing.InputPorts[DmPortName.HdmiIn] != null)
+ {
+ var hdmiInHdcp = routing as IHasHdmiInHdcp;
+ if (hdmiInHdcp != null)
+ {
+ if (rmc.Feedbacks["HdmiInHdcpCapability"] != null)
+ {
+ var intFeedback = rmc.Feedbacks["HdmiInHdcpCapability"] as IntFeedback;
+ if (intFeedback != null)
+ intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
+ }
+ if (rmc.Feedbacks["HdmiInVideoSync"] != null)
+ {
+ var boolFeedback = rmc.Feedbacks["HdmiInVideoSync"] as BoolFeedback;
+ if (boolFeedback != null)
+ boolFeedback.LinkInputSig(trilist.BooleanInput[joinMap.HdmiInputSync.JoinNumber]);
+ }
+ hdcpCapability = hdmiInHdcp.HdmiInHdcpCapability > hdcpCapability
+ ? hdmiInHdcp.HdmiInHdcpCapability
+ : hdcpCapability;
- if (routing.AudioVideoSourceNumericFeedback != null)
- routing.AudioVideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioVideoSource.JoinNumber]);
+ trilist.SetUShortSigAction(joinMap.Port1HdcpState.JoinNumber, a => hdmiInHdcp.SetHdmiInHdcpState((eHdcpCapabilityType)a));
+ }
+ }
+ if (routing.InputPorts[DmPortName.DmIn] != null)
+ {
+ var dmInHdcp = rmc as IHasDmInHdcp;
+
+ if (dmInHdcp != null)
+ {
+ if (rmc.Feedbacks["DmInHdcpCapability"] != null)
+ {
+ var intFeedback = rmc.Feedbacks["DmInHdcpCapability"] as IntFeedback;
+ if (intFeedback != null)
+ intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port2HdcpState.JoinNumber]);
+ }
+
+ hdcpCapability = dmInHdcp.DmInHdcpCapability > hdcpCapability
+ ? dmInHdcp.DmInHdcpCapability
+ : hdcpCapability;
+
+
+ trilist.SetUShortSigAction(joinMap.Port2HdcpState.JoinNumber, a => dmInHdcp.SetDmInHdcpState((eHdcpCapabilityType)a));
+ }
+ }
+
+ trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)hdcpCapability;
+
+ trilist.UShortInput[joinMap.HdcpInputPortCount.JoinNumber].UShortValue = (ushort)routing.InputPorts.Count;
+
+ var dmRmcScalerCBasicVideoMuteWithFeedback = rmc as IBasicVideoMuteWithFeedback;
+
+ if (dmRmcScalerCBasicVideoMuteWithFeedback != null)
+ {
+ Debug.Console(1, this, "Device is IBasicVideoMuteWithFeedback, linking video mute");
+ trilist.SetSigTrueAction(joinMap.VideoMuteToggle.JoinNumber, () => dmRmcScalerCBasicVideoMuteWithFeedback.VideoMuteToggle());
+ trilist.SetSigTrueAction(joinMap.VideoMuteOn.JoinNumber, () => dmRmcScalerCBasicVideoMuteWithFeedback.VideoMuteOn());
+ trilist.SetSigTrueAction(joinMap.VideoMuteOff.JoinNumber, () => dmRmcScalerCBasicVideoMuteWithFeedback.VideoMuteOff());
+ dmRmcScalerCBasicVideoMuteWithFeedback.VideoMuteIsOn.LinkInputSig(trilist.BooleanInput[joinMap.VideoMuteOn.JoinNumber]);
+ dmRmcScalerCBasicVideoMuteWithFeedback.VideoMuteIsOn.LinkComplementInputSig(trilist.BooleanInput[joinMap.VideoMuteOff.JoinNumber]);
+ }
+
+ var routingWithFeedback = routing as IRmcRouting;
+ if (routingWithFeedback == null) return;
+
+ if (routingWithFeedback.AudioVideoSourceNumericFeedback != null)
+ routingWithFeedback.AudioVideoSourceNumericFeedback.LinkInputSig(
+ trilist.UShortInput[joinMap.AudioVideoSource.JoinNumber]);
+
+
+ trilist.SetUShortSigAction(joinMap.AudioVideoSource.JoinNumber,
+ a => routingWithFeedback.ExecuteNumericSwitch(a, 1, eRoutingSignalType.AudioVideo));
+
+ var dmRmcScalerWithVideowall = rmc as DmRmc4kZScalerCController;
+
+ if (dmRmcScalerWithVideowall != null)
+ {
+ trilist.SetUShortSigAction(joinMap.ScalerOutWallMode.JoinNumber, a => dmRmcScalerWithVideowall.SetWallMode(a));
+ trilist.SetUShortSigAction(joinMap.ScalerOutWallModeRaw.JoinNumber, a => dmRmcScalerWithVideowall.SetWallModeRaw(a));
+
+ if (rmc.VideoWallModeFeedback != null)
+ rmc.VideoWallModeFeedback.LinkInputSig(trilist.UShortInput[joinMap.ScalerOutWallMode.JoinNumber]);
+ if (rmc.VideoWallModeRawFeedback != null)
+ rmc.VideoWallModeRawFeedback.LinkInputSig(trilist.UShortInput[joinMap.ScalerOutWallModeRaw.JoinNumber]);
+
+ }
- trilist.SetUShortSigAction(joinMap.AudioVideoSource.JoinNumber, a => routing.ExecuteNumericSwitch(a, 1, eRoutingSignalType.AudioVideo));
}
+
#region Implementation of IDeviceInfoProvider
public DeviceInfo DeviceInfo { get; private set; }
@@ -143,13 +242,13 @@ namespace PepperDash.Essentials.DM
return;
}
-
+
if (args.Text.ToLower().Contains("host"))
{
DeviceInfo.HostName = args.Text.Split(':')[1].Trim();
tcpClient.SendText("maca\r\n");
-
+
return;
}
@@ -202,17 +301,17 @@ namespace PepperDash.Essentials.DM
}
}
- public class DmRmcHelper
- {
- private static readonly Dictionary> ProcessorFactoryDict;
- private static readonly Dictionary> ChassisCpu3Dict;
+ public class DmRmcHelper
+ {
+ private static readonly Dictionary> ProcessorFactoryDict;
+ private static readonly Dictionary> ChassisCpu3Dict;
- private static readonly Dictionary>
- ChassisDict;
+ private static readonly Dictionary>
+ ChassisDict;
- static DmRmcHelper()
- {
- ProcessorFactoryDict = new Dictionary>
+ static DmRmcHelper()
+ {
+ ProcessorFactoryDict = new Dictionary>
{
{"dmrmc100c", (k, n, i) => new DmRmcX100CController(k, n, new DmRmc100C(i, Global.ControlSystem))},
{"dmrmc100s", (k, n, i) => new DmRmc100SController(k, n, new DmRmc100S(i, Global.ControlSystem))},
@@ -306,31 +405,34 @@ namespace PepperDash.Essentials.DM
{"dmrmc4k100c1g", (k,n,i,d) => new DmRmc4k100C1GController(k,n, new DmRmc4K100C1G(i, d))}
};
}
- ///
- /// A factory method for various DmRmcControllers
- ///
- /// device key. Used to uniquely identify device
- /// device name
- /// device type name. Used to retrived the correct device
- /// Config from config file
- ///
- public static CrestronGenericBaseDevice GetDmRmcController(string key, string name, string typeName, DmRmcPropertiesConfig props)
- {
- typeName = typeName.ToLower();
- var ipid = props.Control.IpIdInt;
+ ///
+ /// A factory method for various DmRmcControllers
+ ///
+ /// device key. Used to uniquely identify device
+ /// device name
+ /// device type name. Used to retrived the correct device
+ /// Config from config file
+ ///
+ public static CrestronGenericBaseDevice GetDmRmcController(string key, string name, string typeName, DmRmcPropertiesConfig props)
+ {
+ typeName = typeName.ToLower();
+ var ipid = props.Control.IpIdInt;
- var pKey = props.ParentDeviceKey.ToLower();
+ var pKey = props.ParentDeviceKey.ToLower();
- // Non-DM-chassis endpoints
- return pKey == "processor" ? GetDmRmcControllerForProcessor(key, name, typeName, ipid) : GetDmRmcControllerForChassis(key, name, typeName, props, pKey, ipid);
- }
+ // Non-DM-chassis endpoints
+ return pKey == "processor" ? GetDmRmcControllerForProcessor(key, name, typeName, ipid) : GetDmRmcControllerForChassis(key, name, typeName, props, pKey, ipid);
+ }
- private static CrestronGenericBaseDevice GetDmRmcControllerForChassis(string key, string name, string typeName,
- DmRmcPropertiesConfig props, string pKey, uint ipid)
- {
- var parentDev = DeviceManager.GetDeviceForKey(pKey);
- if (parentDev is DmpsRoutingController)
- {
+ private static CrestronGenericBaseDevice GetDmRmcControllerForChassis(string key, string name, string typeName,
+ DmRmcPropertiesConfig props, string pKey, uint ipid)
+ {
+ var parentDev = DeviceManager.GetDeviceForKey(pKey);
+ CrestronGenericBaseDevice rx;
+ bool useChassisForOfflineFeedback = false;
+
+ if (parentDev is DmpsRoutingController)
+ {
var dmps = parentDev as DmpsRoutingController;
//Check that the input is within range of this chassis' possible inputs
var num = props.ParentOutputNumber;
@@ -342,26 +444,37 @@ namespace PepperDash.Essentials.DM
return null;
}
// Must use different constructor for DMPS4K types. No IPID
- if (Global.ControlSystemIsDmps4kType || typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
+ if (Global.ControlSystemIsDmps4kType)
{
- var rmc = GetDmRmcControllerForDmps4k(key, name, typeName, dmps, props.ParentOutputNumber);
- Debug.Console(0, "DM endpoint output {0} is for Dmps4k, changing online feedback to chassis", num);
- rmc.IsOnline.SetValueFunc(() => dmps.OutputEndpointOnlineFeedbacks[num].BoolValue);
+ rx = GetDmRmcControllerForDmps4k(key, name, typeName, dmps, props.ParentOutputNumber);
+ useChassisForOfflineFeedback = true;
+ }
+ else
+ {
+ rx = GetDmRmcControllerForDmps(key, name, typeName, ipid, dmps, props.ParentOutputNumber);
+ if (typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
+ {
+ useChassisForOfflineFeedback = true;
+ }
+ }
+ if (useChassisForOfflineFeedback)
+ {
+ Debug.Console(0, "DM endpoint output {0} does not have direct online feedback, changing online feedback to chassis", num);
+ rx.IsOnline.SetValueFunc(() => dmps.OutputEndpointOnlineFeedbacks[num].BoolValue);
dmps.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
{
- foreach (var feedback in rmc.Feedbacks)
+ foreach (var feedback in rx.Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
- return rmc;
}
- return GetDmRmcControllerForDmps(key, name, typeName, ipid, dmps, props.ParentOutputNumber);
- }
- else if (parentDev is DmChassisController)
+ return rx;
+ }
+ else if (parentDev is IDmSwitchWithEndpointOnlineFeedback)
{
- var controller = parentDev as DmChassisController;
+ var controller = parentDev as IDmSwitchWithEndpointOnlineFeedback;
var chassis = controller.Chassis;
var num = props.ParentOutputNumber;
Debug.Console(1, "Creating DM Chassis device '{0}'. Output number '{1}'.", key, num);
@@ -371,7 +484,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, "Cannot create DM device '{0}'. Output number '{1}' is out of range",
key, num);
return null;
- }
+ }
controller.RxDictionary.Add(num, key);
// Catch constructor failures, mainly dues to IPID
try
@@ -380,23 +493,33 @@ namespace PepperDash.Essentials.DM
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps ||
- chassis is DmMd128x128 || chassis is DmMd64x64
- || typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
+ chassis is DmMd128x128 || chassis is DmMd64x64)
{
- var rmc = GetDmRmcControllerForCpu3Chassis(key, name, typeName, chassis, num, parentDev);
- Debug.Console(0, "DM endpoint output {0} is for Cpu3, changing online feedback to chassis", num);
- rmc.IsOnline.SetValueFunc(() => controller.OutputEndpointOnlineFeedbacks[num].BoolValue);
- controller.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
- {
- foreach (var feedback in rmc.Feedbacks)
- {
- if (feedback != null)
- feedback.FireUpdate();
- }
- };
- return rmc;
+ rx = GetDmRmcControllerForCpu3Chassis(key, name, typeName, chassis, num, parentDev);
+ useChassisForOfflineFeedback = true;
}
- return GetDmRmcControllerForCpu2Chassis(key, name, typeName, ipid, chassis, num, parentDev);
+ else
+ {
+ rx = GetDmRmcControllerForCpu2Chassis(key, name, typeName, ipid, chassis, num, parentDev);
+ if (typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
+ {
+ useChassisForOfflineFeedback = true;
+ }
+ }
+ if (useChassisForOfflineFeedback)
+ {
+ Debug.Console(0, "DM endpoint output {0} does not have direct online feedback, changing online feedback to chassis", num);
+ rx.IsOnline.SetValueFunc(() => controller.OutputEndpointOnlineFeedbacks[num].BoolValue);
+ controller.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
+ {
+ foreach (var feedback in rx.Feedbacks)
+ {
+ if (feedback != null)
+ feedback.FireUpdate();
+ }
+ };
+ }
+ return rx;
}
catch (Exception e)
{
@@ -410,31 +533,31 @@ namespace PepperDash.Essentials.DM
key, pKey);
return null;
}
- }
+ }
- private static CrestronGenericBaseDevice GetDmRmcControllerForCpu2Chassis(string key, string name, string typeName,
- uint ipid, Switch chassis, uint num, IKeyed parentDev)
- {
- Func handler;
- if (ChassisDict.TryGetValue(typeName.ToLower(), out handler))
- {
- return handler(key, name, ipid, chassis.Outputs[num]);
- }
- Debug.Console(0, "Cannot create DM-RMC of type '{0}' with parent device {1}", typeName, parentDev.Key);
- return null;
- }
+ private static CrestronGenericBaseDevice GetDmRmcControllerForCpu2Chassis(string key, string name, string typeName,
+ uint ipid, Switch chassis, uint num, IKeyed parentDev)
+ {
+ Func handler;
+ if (ChassisDict.TryGetValue(typeName.ToLower(), out handler))
+ {
+ return handler(key, name, ipid, chassis.Outputs[num]);
+ }
+ Debug.Console(0, "Cannot create DM-RMC of type '{0}' with parent device {1}", typeName, parentDev.Key);
+ return null;
+ }
- private static CrestronGenericBaseDevice GetDmRmcControllerForCpu3Chassis(string key, string name, string typeName,
- Switch chassis, uint num, IKeyed parentDev)
- {
- Func cpu3Handler;
- if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out cpu3Handler))
- {
- return cpu3Handler(key, name, chassis.Outputs[num]);
- }
- Debug.Console(0, "Cannot create DM-RMC of type '{0}' with parent device {1}", typeName, parentDev.Key);
- return null;
- }
+ private static CrestronGenericBaseDevice GetDmRmcControllerForCpu3Chassis(string key, string name, string typeName,
+ Switch chassis, uint num, IKeyed parentDev)
+ {
+ Func cpu3Handler;
+ if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out cpu3Handler))
+ {
+ return cpu3Handler(key, name, chassis.Outputs[num]);
+ }
+ Debug.Console(0, "Cannot create DM-RMC of type '{0}' with parent device {1}", typeName, parentDev.Key);
+ return null;
+ }
private static CrestronGenericBaseDevice GetDmRmcControllerForDmps(string key, string name, string typeName,
uint ipid, DmpsRoutingController controller, uint num)
@@ -458,51 +581,49 @@ namespace PepperDash.Essentials.DM
return null;
}
- private static CrestronGenericBaseDevice GetDmRmcControllerForDmps4k(string key, string name, string typeName,
- DmpsRoutingController controller, uint num)
- {
- Func dmps4kHandler;
- if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmps4kHandler))
- {
- var output = controller.Dmps.SwitcherOutputs[num] as DMOutput;
+ private static CrestronGenericBaseDevice GetDmRmcControllerForDmps4k(string key, string name, string typeName,
+ DmpsRoutingController controller, uint num)
+ {
+ Func dmps4kHandler;
+ if (ChassisCpu3Dict.TryGetValue(typeName.ToLower(), out dmps4kHandler))
+ {
+ var output = controller.Dmps.SwitcherOutputs[num] as DMOutput;
- if (output != null)
- {
- return dmps4kHandler(key, name, output);
- }
- Debug.Console(0, Debug.ErrorLogLevel.Error,
- "Cannot attach DM-RMC of type '{0}' to output {1} on DMPS-4K chassis. Output is not a DM Output.",
- typeName, num);
- return null;
- }
+ if (output != null)
+ {
+ return dmps4kHandler(key, name, output);
+ }
+ Debug.Console(0, Debug.ErrorLogLevel.Error,
+ "Cannot attach DM-RMC of type '{0}' to output {1} on DMPS-4K chassis. Output is not a DM Output.",
+ typeName, num);
+ return null;
+ }
Debug.Console(0, Debug.ErrorLogLevel.Error, "Cannot create DM-RMC of type '{0}' to output {1} on DMPS-4K chassis", typeName, num);
- return null;
- }
+ return null;
+ }
- private static CrestronGenericBaseDevice GetDmRmcControllerForProcessor(string key, string name, string typeName, uint ipid)
- {
- try
- {
- Func handler;
+ private static CrestronGenericBaseDevice GetDmRmcControllerForProcessor(string key, string name, string typeName, uint ipid)
+ {
+ try
+ {
+ Func handler;
- if (ProcessorFactoryDict.TryGetValue(typeName.ToLower(), out handler))
- {
- return handler(key, name, ipid);
- }
- Debug.Console(0, "Cannot create DM-RMC of type: '{0}'", typeName);
+ if (ProcessorFactoryDict.TryGetValue(typeName.ToLower(), out handler))
+ {
+ return handler(key, name, ipid);
+ }
+ Debug.Console(0, "Cannot create DM-RMC of type: '{0}'", typeName);
- return null;
- }
- catch (Exception e)
- {
- Debug.Console(0, "[{0}] WARNING: Cannot create DM-RMC device: {1}", key, e.Message);
return null;
- }
- }
-
-
- }
+ }
+ catch (Exception e)
+ {
+ Debug.Console(0, "[{0}] WARNING: Cannot create DM-RMC device: {1}", key, e.Message);
+ return null;
+ }
+ }
+ }
public class DmRmcControllerFactory : EssentialsDeviceFactory
{
@@ -522,7 +643,7 @@ namespace PepperDash.Essentials.DM
var props = JsonConvert.DeserializeObject
(dc.Properties.ToString());
- return DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props);
+ return DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props);
}
}
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs
index d1f2daa1..169995d8 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Receivers/DmRmcScalerCController.cs
@@ -51,6 +51,7 @@ namespace PepperDash.Essentials.DM
InputPorts = new RoutingPortCollection {DmIn};
OutputPorts = new RoutingPortCollection {HdmiOut};
+
// Set Ports for CEC
HdmiOut.Port = _rmc.HdmiOutput;
}
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs
index fe4454b9..10507c4d 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx200Controller.cs
@@ -1,41 +1,41 @@
using System;
using System.Linq;
-using Crestron.SimplSharpPro;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.DM
-{
- // using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
-
- ///
- /// Controller class for all DM-TX-201C/S/F transmitters
+using Crestron.SimplSharpPro;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.DM
+{
+ // using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
+
+ ///
+ /// Controller class for all DM-TX-201C/S/F transmitters
///
[Description("Wrapper class for DM-TX-200-C")]
- public class DmTx200Controller : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
- {
- public DmTx200C2G Tx { get; private set; }
-
- public RoutingInputPortWithVideoStatuses HdmiInput { get; private set; }
- public RoutingInputPortWithVideoStatuses VgaInput { get; private set; }
- public RoutingOutputPort DmOutput { get; private set; }
-
- public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
- public IntFeedback VideoSourceNumericFeedback { get; protected set; }
- public IntFeedback AudioSourceNumericFeedback { get; protected set; }
- public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; } //actually state
- public BoolFeedback HdmiVideoSyncFeedback { get; protected set; }
- public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
-
- public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
-
- public IntFeedback VgaBrightnessFeedback { get; protected set; }
+ public class DmTx200Controller : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
+ {
+ public DmTx200C2G Tx { get; private set; }
+
+ public RoutingInputPortWithVideoStatuses HdmiInput { get; private set; }
+ public RoutingInputPortWithVideoStatuses VgaInput { get; private set; }
+ public RoutingOutputPort DmOutput { get; private set; }
+
+ public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
+ public IntFeedback VideoSourceNumericFeedback { get; protected set; }
+ public IntFeedback AudioSourceNumericFeedback { get; protected set; }
+ public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; } //actually state
+ public BoolFeedback HdmiVideoSyncFeedback { get; protected set; }
+ public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
+
+ public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
+
+ public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
@@ -49,57 +49,57 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
- }
-
-
- ///
- /// Helps get the "real" inputs, including when in Auto
- ///
- public DmTx200Base.eSourceSelection ActualActiveVideoInput
- {
- get
- {
- if (Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Digital ||
- Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Analog ||
- Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Disable)
- return Tx.VideoSourceFeedback;
- if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue)
- return DmTx200Base.eSourceSelection.Digital;
-
- return Tx.VgaInput.SyncDetectedFeedback.BoolValue ? DmTx200Base.eSourceSelection.Analog : DmTx200Base.eSourceSelection.Disable;
- }
- }
-
- public RoutingPortCollection InputPorts
- {
- get
- {
- return new RoutingPortCollection
- {
- HdmiInput,
- VgaInput,
- AnyVideoInput
- };
- }
- }
-
- public RoutingPortCollection OutputPorts
- {
- get
- {
- return new RoutingPortCollection { DmOutput };
- }
- }
-
- ///
- ///
- ///
- ///
- ///
- ///
- public DmTx200Controller(string key, string name, DmTx200C2G tx, bool preventRegistration)
- : base(key, name, tx)
- {
+ }
+
+
+ ///
+ /// Helps get the "real" inputs, including when in Auto
+ ///
+ public DmTx200Base.eSourceSelection ActualActiveVideoInput
+ {
+ get
+ {
+ if (Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Digital ||
+ Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Analog ||
+ Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Disable)
+ return Tx.VideoSourceFeedback;
+ if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue)
+ return DmTx200Base.eSourceSelection.Digital;
+
+ return Tx.VgaInput.SyncDetectedFeedback.BoolValue ? DmTx200Base.eSourceSelection.Analog : DmTx200Base.eSourceSelection.Disable;
+ }
+ }
+
+ public RoutingPortCollection InputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection
+ {
+ HdmiInput,
+ VgaInput,
+ AnyVideoInput
+ };
+ }
+ }
+
+ public RoutingPortCollection OutputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection { DmOutput };
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public DmTx200Controller(string key, string name, DmTx200C2G tx, bool preventRegistration)
+ : base(key, name, tx)
+ {
Tx = tx;
PreventRegistration = preventRegistration;
@@ -116,300 +116,300 @@ namespace PepperDash.Essentials.DM
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = DmTx200Base.eSourceSelection.Analog
- };
-
- ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
- () => ActualActiveVideoInput.ToString());
-
- Tx.HdmiInput.InputStreamChange += InputStreamChangeEvent;
- Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
- Tx.BaseEvent += Tx_BaseEvent;
- Tx.OnlineStatusChange += Tx_OnlineStatusChange;
-
- VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
- AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
-
+ };
+
+ ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
+ () => ActualActiveVideoInput.ToString());
+
+ Tx.HdmiInput.InputStreamChange += InputStreamChangeEvent;
+ Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
+ Tx.BaseEvent += Tx_BaseEvent;
+ Tx.OnlineStatusChange += Tx_OnlineStatusChange;
+
+ VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
+ AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
+
HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () => tx.HdmiInput.HdcpSupportOnFeedback.BoolValue ? 1 : 0);
//setting this on the base class so that we can get it easily on the chassis.
- HdcpStateFeedback = HdmiInHdcpCapabilityFeedback;
-
- HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
-
- HdmiVideoSyncFeedback = new BoolFeedback(() => tx.HdmiInput.SyncDetectedFeedback.BoolValue);
-
- VgaVideoSyncFeedback = new BoolFeedback(() => tx.VgaInput.SyncDetectedFeedback.BoolValue);
-
- FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
-
- VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
- VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
-
- tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
-
-
- var combinedFuncs = new VideoStatusFuncsWrapper
- {
- HdcpActiveFeedbackFunc = () =>
- (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
- && tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
-
- HdcpStateFeedbackFunc = () => ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital ? tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString() : "",
-
- VideoResolutionFeedbackFunc = () =>
- {
- if (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital)
- return tx.HdmiInput.VideoAttributes.GetVideoResolutionString();
- return ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog ? tx.VgaInput.VideoAttributes.GetVideoResolutionString() : "";
- },
- VideoSyncFeedbackFunc = () =>
- (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
- && tx.HdmiInput.SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog
- && tx.VgaInput.SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Auto
- && (tx.VgaInput.SyncDetectedFeedback.BoolValue || tx.HdmiInput.SyncDetectedFeedback.BoolValue))
-
- };
-
- AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
-
- DmOutput = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.DmCat, null, this);
-
- AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
- AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
- AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
- AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, HdmiVideoSyncFeedback,
- VgaVideoSyncFeedback);
-
- // Set Ports for CEC
- HdmiInput.Port = Tx.HdmiInput;
- VgaInput.Port = Tx.VgaInput;
- DmOutput.Port = Tx.DmOutput;
- }
-
- private void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
- switch (args.EventId)
- {
- case EndpointInputStreamEventIds.FreeRunFeedbackEventId:
- FreeRunEnabledFeedback.FireUpdate();
- break;
- case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
- VgaVideoSyncFeedback.FireUpdate();
- break;
- }
- }
-
- void VideoControls_ControlChange(object sender, GenericEventArgs args)
- {
- var id = args.EventId;
- Debug.Console(2, this, "EventId {0}", args.EventId);
-
- switch (id)
- {
- case VideoControlsEventIds.BrightnessFeedbackEventId:
- VgaBrightnessFeedback.FireUpdate();
- break;
- case VideoControlsEventIds.ContrastFeedbackEventId:
- VgaContrastFeedback.FireUpdate();
- break;
- }
- }
-
+ HdcpStateFeedback = HdmiInHdcpCapabilityFeedback;
+
+ HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
+
+ HdmiVideoSyncFeedback = new BoolFeedback(() => tx.HdmiInput.SyncDetectedFeedback.BoolValue);
+
+ VgaVideoSyncFeedback = new BoolFeedback(() => tx.VgaInput.SyncDetectedFeedback.BoolValue);
+
+ FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
+
+ VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
+ VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
+
+ tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
+
+
+ var combinedFuncs = new VideoStatusFuncsWrapper
+ {
+ HdcpActiveFeedbackFunc = () =>
+ (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
+ && tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
+
+ HdcpStateFeedbackFunc = () => ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital ? tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString() : "",
+
+ VideoResolutionFeedbackFunc = () =>
+ {
+ if (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital)
+ return tx.HdmiInput.VideoAttributes.GetVideoResolutionString();
+ return ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog ? tx.VgaInput.VideoAttributes.GetVideoResolutionString() : "";
+ },
+ VideoSyncFeedbackFunc = () =>
+ (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
+ && tx.HdmiInput.SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog
+ && tx.VgaInput.SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Auto
+ && (tx.VgaInput.SyncDetectedFeedback.BoolValue || tx.HdmiInput.SyncDetectedFeedback.BoolValue))
+
+ };
+
+ AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
+
+ DmOutput = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.DmCat, null, this);
+
+ AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
+ AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
+ AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
+ AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, HdmiVideoSyncFeedback,
+ VgaVideoSyncFeedback);
+
+ // Set Ports for CEC
+ HdmiInput.Port = Tx.HdmiInput;
+ VgaInput.Port = Tx.VgaInput;
+ DmOutput.Port = Tx.DmOutput;
+ }
+
+ private void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
+ switch (args.EventId)
+ {
+ case EndpointInputStreamEventIds.FreeRunFeedbackEventId:
+ FreeRunEnabledFeedback.FireUpdate();
+ break;
+ case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
+ VgaVideoSyncFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ void VideoControls_ControlChange(object sender, GenericEventArgs args)
+ {
+ var id = args.EventId;
+ Debug.Console(2, this, "EventId {0}", args.EventId);
+
+ switch (id)
+ {
+ case VideoControlsEventIds.BrightnessFeedbackEventId:
+ VgaBrightnessFeedback.FireUpdate();
+ break;
+ case VideoControlsEventIds.ContrastFeedbackEventId:
+ VgaContrastFeedback.FireUpdate();
+ break;
+ }
+ }
+
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();
+ 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));
- }
-
- public override bool CustomActivate()
- {
-
- Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiInput, a.EventId);
- Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(HdmiInput, a.EventId);
-
- Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaInput, a.EventId);
- Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(VgaInput, a.EventId);
-
- // Base does register and sets up comm monitoring.
- return base.CustomActivate();
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
-
- if (HdmiVideoSyncFeedback != null)
- {
- HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
- }
- if (VgaVideoSyncFeedback != null)
- {
- VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
- }
-
- LinkDmTxToApi(this, trilist, joinMap, bridge);
- }
-
- ///
- /// Enables or disables free run
- ///
- ///
- public void SetFreeRunEnabled(bool enable)
- {
- Tx.VgaInput.FreeRun = enable ? eDmFreeRunSetting.Enabled : eDmFreeRunSetting.Disabled;
- }
-
- ///
- /// Sets the VGA brightness level
- ///
- ///
- public void SetVgaBrightness(ushort level)
- {
- Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
- }
-
- ///
- /// Sets the VGA contrast level
- ///
- ///
- public void SetVgaContrast(ushort level)
- {
- Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
- }
-
- public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
- {
- Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
-
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(DmTx200Base.eSourceSelection.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(HdmiInput.Selector, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(VgaInput.Selector, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(DmTx200Base.eSourceSelection.Disable, null, type);
- break;
- }
- }
- }
-
- public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
- {
- if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
- Tx.VideoSource = (DmTx200Base.eSourceSelection)inputSelector;
- if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
- Tx.AudioSource = (DmTx200Base.eSourceSelection)inputSelector;
- }
-
- void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
- {
- var id = args.EventId;
- Debug.Console(2, this, "EventId {0}", args.EventId);
-
- switch (id)
- {
+ OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localAudioInputPort, eRoutingSignalType.Audio));
+ }
+
+ public override bool CustomActivate()
+ {
+
+ Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiInput, a.EventId);
+ Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(HdmiInput, a.EventId);
+
+ Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaInput, a.EventId);
+ Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(VgaInput, a.EventId);
+
+ // Base does register and sets up comm monitoring.
+ return base.CustomActivate();
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
+
+ if (HdmiVideoSyncFeedback != null)
+ {
+ HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
+ }
+ if (VgaVideoSyncFeedback != null)
+ {
+ VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
+ }
+
+ LinkDmTxToApi(this, trilist, joinMap, bridge);
+ }
+
+ ///
+ /// Enables or disables free run
+ ///
+ ///
+ public void SetFreeRunEnabled(bool enable)
+ {
+ Tx.VgaInput.FreeRun = enable ? eDmFreeRunSetting.Enabled : eDmFreeRunSetting.Disabled;
+ }
+
+ ///
+ /// Sets the VGA brightness level
+ ///
+ ///
+ public void SetVgaBrightness(ushort level)
+ {
+ Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
+ }
+
+ ///
+ /// Sets the VGA contrast level
+ ///
+ ///
+ public void SetVgaContrast(ushort level)
+ {
+ Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
+ }
+
+ public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
+ {
+ Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
+
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(DmTx200Base.eSourceSelection.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(HdmiInput.Selector, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(VgaInput.Selector, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(DmTx200Base.eSourceSelection.Disable, null, type);
+ break;
+ }
+ }
+ }
+
+ public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
+ {
+ if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
+ Tx.VideoSource = (DmTx200Base.eSourceSelection)inputSelector;
+ if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
+ Tx.AudioSource = (DmTx200Base.eSourceSelection)inputSelector;
+ }
+
+ 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 => (DmTx200Base.eSourceSelection)p.Selector == Tx.VideoSourceFeedback);
- Debug.Console(2, this, " Video Source: {0}", Tx.VideoSourceFeedback);
- VideoSourceNumericFeedback.FireUpdate();
+ var localVideoInputPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)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;
+ break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
- var localInputAudioPort = InputPorts.FirstOrDefault(p => (DmTx200Base.eSourceSelection)p.Selector == Tx.AudioSourceFeedback);
- 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();
- OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
- break;
- }
- }
-
- void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
- Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
-
- switch (args.EventId)
- {
- case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
- HdmiInHdcpCapabilityFeedback.FireUpdate();
- break;
- case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
- HdmiInHdcpCapabilityFeedback.FireUpdate();
- break;
- case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
- HdmiVideoSyncFeedback.FireUpdate();
- break;
- }
- }
-
- ///
- /// Relays the input stream change to the appropriate RoutingInputPort.
- ///
- void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
- {
- return;
- }
- inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
- }
-
- ///
- /// Relays the VideoAttributes change to a RoutingInputPort
- ///
- void FireVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
- //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
- // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
- switch (eventId)
- {
- case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
- inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HdcpStateFeedbackEventId:
- inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
- case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- }
- }
-
- }
+ OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
+ break;
+ }
+ }
+
+ void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
+ Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
+
+ switch (args.EventId)
+ {
+ case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
+ HdmiInHdcpCapabilityFeedback.FireUpdate();
+ break;
+ case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
+ HdmiInHdcpCapabilityFeedback.FireUpdate();
+ break;
+ case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
+ HdmiVideoSyncFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ ///
+ /// Relays the input stream change to the appropriate RoutingInputPort.
+ ///
+ void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
+ {
+ return;
+ }
+ inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
+ }
+
+ ///
+ /// Relays the VideoAttributes change to a RoutingInputPort
+ ///
+ void FireVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
+ //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
+ // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
+ switch (eventId)
+ {
+ case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
+ inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HdcpStateFeedbackEventId:
+ inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
+ case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs
index 660d2fec..ae3dd7fc 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx201CController.cs
@@ -8,33 +8,33 @@ using System.Linq;
using PepperDash.Core;
using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-
-namespace PepperDash.Essentials.DM
-{
- ///
- /// Controller class for all DM-TX-201C/S/F transmitters
+using PepperDash.Essentials.Core.Bridges;
+
+namespace PepperDash.Essentials.DM
+{
+ ///
+ /// Controller class for all DM-TX-201C/S/F transmitters
///
[Description("Wrapper class for DM-TX-201-C")]
- public class DmTx201CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
- {
- public DmTx201C Tx { get; private set; }
-
- public RoutingInputPortWithVideoStatuses HdmiInput { get; private set; }
- public RoutingInputPortWithVideoStatuses VgaInput { get; private set; }
- public RoutingOutputPort DmOutput { get; private set; }
- public RoutingOutputPort HdmiLoopOut { get; private set; }
-
- public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
- public IntFeedback VideoSourceNumericFeedback { get; protected set; }
- public IntFeedback AudioSourceNumericFeedback { get; protected set; }
- public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
- public BoolFeedback HdmiVideoSyncFeedback { get; protected set; }
- public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
-
- public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
-
- public IntFeedback VgaBrightnessFeedback { get; protected set; }
+ public class DmTx201CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFreeRun, IVgaBrightnessContrastControls
+ {
+ public DmTx201C Tx { get; private set; }
+
+ public RoutingInputPortWithVideoStatuses HdmiInput { get; private set; }
+ public RoutingInputPortWithVideoStatuses VgaInput { get; private set; }
+ public RoutingOutputPort DmOutput { get; private set; }
+ public RoutingOutputPort HdmiLoopOut { get; private set; }
+
+ public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
+ public IntFeedback VideoSourceNumericFeedback { get; protected set; }
+ public IntFeedback AudioSourceNumericFeedback { get; protected set; }
+ public IntFeedback HdmiInHdcpCapabilityFeedback { get; protected set; }
+ public BoolFeedback HdmiVideoSyncFeedback { get; protected set; }
+ public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
+
+ public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
+
+ public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
@@ -48,61 +48,61 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
- }
-
- ///
- /// Helps get the "real" inputs, including when in Auto
- ///
- public DmTx200Base.eSourceSelection ActualActiveVideoInput
- {
- get
- {
- if (Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Digital ||
- Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Analog ||
- Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Disable)
- return Tx.VideoSourceFeedback;
- else // auto
- {
- if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue)
- return DmTx200Base.eSourceSelection.Digital;
- else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue)
- return DmTx200Base.eSourceSelection.Analog;
- else
- return DmTx200Base.eSourceSelection.Disable;
- }
- }
- }
-
- public RoutingPortCollection InputPorts
- {
- get
- {
- return new RoutingPortCollection
- {
- HdmiInput,
- VgaInput,
- AnyVideoInput
- };
- }
- }
-
- public RoutingPortCollection OutputPorts
- {
- get
- {
- return new RoutingPortCollection { DmOutput, HdmiLoopOut };
- }
- }
-
- ///
- ///
- ///
- ///
- ///
+ }
+
+ ///
+ /// Helps get the "real" inputs, including when in Auto
+ ///
+ public DmTx200Base.eSourceSelection ActualActiveVideoInput
+ {
+ get
+ {
+ if (Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Digital ||
+ Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Analog ||
+ Tx.VideoSourceFeedback == DmTx200Base.eSourceSelection.Disable)
+ return Tx.VideoSourceFeedback;
+ else // auto
+ {
+ if (Tx.HdmiInput.SyncDetectedFeedback.BoolValue)
+ return DmTx200Base.eSourceSelection.Digital;
+ else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue)
+ return DmTx200Base.eSourceSelection.Analog;
+ else
+ return DmTx200Base.eSourceSelection.Disable;
+ }
+ }
+ }
+
+ public RoutingPortCollection InputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection
+ {
+ HdmiInput,
+ VgaInput,
+ AnyVideoInput
+ };
+ }
+ }
+
+ public RoutingPortCollection OutputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection { DmOutput, HdmiLoopOut };
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public DmTx201CController(string key, string name, DmTx201C tx, bool preventRegistration)
- : base(key, name, tx)
- {
+ public DmTx201CController(string key, string name, DmTx201C tx, bool preventRegistration)
+ : base(key, name, tx)
+ {
Tx = tx;
PreventRegistration = preventRegistration;
@@ -119,89 +119,89 @@ namespace PepperDash.Essentials.DM
VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = DmTx200Base.eSourceSelection.Analog
- };
-
- ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
- () => ActualActiveVideoInput.ToString());
-
+ };
+
+ ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
+ () => ActualActiveVideoInput.ToString());
+
Tx.HdmiInput.InputStreamChange += InputStreamChangeEvent;
- Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
- Tx.BaseEvent += Tx_BaseEvent;
- Tx.OnlineStatusChange += new OnlineStatusChangeEventHandler(Tx_OnlineStatusChange);
-
- VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
-
+ Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
+ Tx.BaseEvent += Tx_BaseEvent;
+ Tx.OnlineStatusChange += new OnlineStatusChangeEventHandler(Tx_OnlineStatusChange);
+
+ VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
+
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
HdmiInHdcpCapabilityFeedback = new IntFeedback("HdmiInHdcpCapability", () =>
(tx.HdmiInput.HdcpSupportOnFeedback.BoolValue ? 1 : 0));
- HdcpStateFeedback = HdmiInHdcpCapabilityFeedback;
-
- HdmiVideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInput.SyncDetectedFeedback.BoolValue);
-
- VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue);
-
- FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
-
- VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
-
- VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
-
- tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
-
- HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
-
- var combinedFuncs = new VideoStatusFuncsWrapper
- {
- HdcpActiveFeedbackFunc = () =>
- (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
- && tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
+ HdcpStateFeedback = HdmiInHdcpCapabilityFeedback;
- HdcpStateFeedbackFunc = () => ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital ?
- tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString() : "",
-
- VideoResolutionFeedbackFunc = () =>
- {
- if (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital)
- return tx.HdmiInput.VideoAttributes.GetVideoResolutionString();
- return ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog ?
- tx.VgaInput.VideoAttributes.GetVideoResolutionString() : "";
- },
-
- VideoSyncFeedbackFunc = () =>
- (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
- && tx.HdmiInput.SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog
- && tx.VgaInput.SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Auto
- && (tx.VgaInput.SyncDetectedFeedback.BoolValue || tx.HdmiInput.SyncDetectedFeedback.BoolValue))
-
- };
-
- AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
-
- DmOutput = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, null, this);
- HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.Hdmi, null, this);
-
- AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
- AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
- AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
- AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, HdmiVideoSyncFeedback,
- VgaVideoSyncFeedback);
-
- // Set Ports for CEC
- HdmiInput.Port = Tx.HdmiInput;
- VgaInput.Port = Tx.VgaInput;
- HdmiLoopOut.Port = Tx.HdmiOutput;
- DmOutput.Port = Tx.DmOutput;
- }
-
- void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
- {
- var id = args.EventId;
+ HdmiVideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInput.SyncDetectedFeedback.BoolValue);
+
+ VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue);
+
+ FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
+
+ VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
+
+ VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
+
+ tx.VgaInput.VideoControls.ControlChange += VideoControls_ControlChange;
+
+ HdcpSupportCapability = eHdcpCapabilityType.HdcpAutoSupport;
+
+ var combinedFuncs = new VideoStatusFuncsWrapper
+ {
+ HdcpActiveFeedbackFunc = () =>
+ (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
+ && tx.HdmiInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
+
+ HdcpStateFeedbackFunc = () => ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital ?
+ tx.HdmiInput.VideoAttributes.HdcpStateFeedback.ToString() : "",
+
+ VideoResolutionFeedbackFunc = () =>
+ {
+ if (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital)
+ return tx.HdmiInput.VideoAttributes.GetVideoResolutionString();
+ return ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog ?
+ tx.VgaInput.VideoAttributes.GetVideoResolutionString() : "";
+ },
+
+ VideoSyncFeedbackFunc = () =>
+ (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Digital
+ && tx.HdmiInput.SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Analog
+ && tx.VgaInput.SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == DmTx200Base.eSourceSelection.Auto
+ && (tx.VgaInput.SyncDetectedFeedback.BoolValue || tx.HdmiInput.SyncDetectedFeedback.BoolValue))
+
+ };
+
+ AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
+
+ DmOutput = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, null, this);
+ HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.Hdmi, null, this);
+
+ AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
+ AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
+ AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
+ AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiInHdcpCapabilityFeedback, HdmiVideoSyncFeedback,
+ VgaVideoSyncFeedback);
+
+ // Set Ports for CEC
+ HdmiInput.Port = Tx.HdmiInput;
+ VgaInput.Port = Tx.VgaInput;
+ HdmiLoopOut.Port = Tx.HdmiOutput;
+ DmOutput.Port = Tx.DmOutput;
+ }
+
+ void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
+ {
+ var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
switch (id)
@@ -212,7 +212,7 @@ namespace PepperDash.Essentials.DM
case VideoControlsEventIds.ContrastFeedbackEventId:
VgaContrastFeedback.FireUpdate();
break;
- }
+ }
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
@@ -228,7 +228,7 @@ namespace PepperDash.Essentials.DM
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)
{
@@ -241,107 +241,107 @@ namespace PepperDash.Essentials.DM
VgaVideoSyncFeedback.FireUpdate();
break;
}
- }
-
- public override bool CustomActivate()
- {
- Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiInput, a.EventId);
- Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(HdmiInput, a.EventId);
-
- Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaInput, a.EventId);
- Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(VgaInput, a.EventId);
-
- // Base does register and sets up comm monitoring.
- return base.CustomActivate();
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
-
- if (HdmiVideoSyncFeedback != null)
- {
- HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
- }
- if (VgaVideoSyncFeedback != null)
- {
- VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
- }
-
- LinkDmTxToApi(this, trilist, joinMap, bridge);
- }
-
- ///
- /// Enables or disables free run
- ///
- ///
- public void SetFreeRunEnabled(bool enable)
+ }
+
+ public override bool CustomActivate()
+ {
+ Tx.HdmiInput.InputStreamChange += (o, a) => FowardInputStreamChange(HdmiInput, a.EventId);
+ Tx.HdmiInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(HdmiInput, a.EventId);
+
+ Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaInput, a.EventId);
+ Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => FireVideoAttributeChange(VgaInput, a.EventId);
+
+ // Base does register and sets up comm monitoring.
+ return base.CustomActivate();
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
- Tx.VgaInput.FreeRun = enable ? eDmFreeRunSetting.Enabled : eDmFreeRunSetting.Disabled;
- }
-
- ///
- /// Sets the VGA brightness level
- ///
- ///
- public void SetVgaBrightness(ushort level)
- {
- Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
- }
-
- ///
- /// Sets the VGA contrast level
- ///
- ///
- public void SetVgaContrast(ushort level)
- {
- Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
- }
-
- ///
- /// Switches the audio/video source based on the integer value (0-Auto, 1-HDMI, 2-VGA, 3-Disable)
- ///
- ///
- ///
- ///
- public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
- {
- Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
-
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(DmTx200Base.eSourceSelection.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(HdmiInput.Selector, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(VgaInput.Selector, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(DmTx200Base.eSourceSelection.Disable, null, type);
- break;
- }
- }
- }
-
- public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
- {
- if((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
- Tx.VideoSource = (DmTx200Base.eSourceSelection)inputSelector;
- if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
- Tx.AudioSource = (DmTx200Base.eSourceSelection)inputSelector;
- }
-
- void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
+ var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
+
+ if (HdmiVideoSyncFeedback != null)
+ {
+ HdmiVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
+ }
+ if (VgaVideoSyncFeedback != null)
+ {
+ VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
+ }
+
+ LinkDmTxToApi(this, trilist, joinMap, bridge);
+ }
+
+ ///
+ /// Enables or disables free run
+ ///
+ ///
+ public void SetFreeRunEnabled(bool enable)
+ {
+ Tx.VgaInput.FreeRun = enable ? eDmFreeRunSetting.Enabled : eDmFreeRunSetting.Disabled;
+ }
+
+ ///
+ /// Sets the VGA brightness level
+ ///
+ ///
+ public void SetVgaBrightness(ushort level)
+ {
+ Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
+ }
+
+ ///
+ /// Sets the VGA contrast level
+ ///
+ ///
+ public void SetVgaContrast(ushort level)
+ {
+ Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
+ }
+
+ ///
+ /// Switches the audio/video source based on the integer value (0-Auto, 1-HDMI, 2-VGA, 3-Disable)
+ ///
+ ///
+ ///
+ ///
+ public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
+ {
+ Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
+
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(DmTx200Base.eSourceSelection.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(HdmiInput.Selector, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(VgaInput.Selector, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(DmTx200Base.eSourceSelection.Disable, null, type);
+ break;
+ }
+ }
+ }
+
+ public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
+ {
+ if((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
+ Tx.VideoSource = (DmTx200Base.eSourceSelection)inputSelector;
+ if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
+ Tx.AudioSource = (DmTx200Base.eSourceSelection)inputSelector;
+ }
+
+ void Tx_BaseEvent(GenericBase device, BaseEventArgs args)
{
var id = args.EventId;
Debug.Console(2, this, "EventId {0}", args.EventId);
@@ -361,11 +361,11 @@ namespace PepperDash.Essentials.DM
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
- }
- }
-
- void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
+ }
+ }
+
+ void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
switch (args.EventId)
@@ -379,52 +379,52 @@ namespace PepperDash.Essentials.DM
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
HdmiVideoSyncFeedback.FireUpdate();
break;
- }
-
- }
-
- ///
- /// Relays the input stream change to the appropriate RoutingInputPort.
- ///
- void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
+ }
+
+ }
+
+ ///
+ /// Relays the input stream change to the appropriate RoutingInputPort.
+ ///
+ void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
{
- return;
+ return;
}
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
- }
-
- ///
- /// Relays the VideoAttributes change to a RoutingInputPort
- ///
- void FireVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
- //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
- // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
- switch (eventId)
- {
- case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
- inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HdcpStateFeedbackEventId:
- inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
- case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- }
- }
-
- }
+ AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
+ }
+
+ ///
+ /// Relays the VideoAttributes change to a RoutingInputPort
+ ///
+ void FireVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
+ //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
+ // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
+ switch (eventId)
+ {
+ case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
+ inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HdcpStateFeedbackEventId:
+ inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
+ case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ }
+ }
+
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs
index 5bbf5fd5..3c7ffffa 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k100Controller.cs
@@ -78,6 +78,8 @@ namespace PepperDash.Essentials.DM
IsOnline.SetValueFunc(() => controller.InputEndpointOnlineFeedbacks[num].BoolValue);
controller.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
+ PreventRegistration = true;
+ tx.Register();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs
index 387562e4..6614bcb4 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k202CController.cs
@@ -1,42 +1,42 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharpPro;
-//using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-using PepperDash.Essentials.DM.Config;
-
-namespace PepperDash.Essentials.DM
-{
- using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
- using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
-
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+//using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.DM.Config;
+
+namespace PepperDash.Essentials.DM
+{
+ using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
+ using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
+
[Description("Wrapper class for DM-TX-4K-202-C")]
- public class DmTx4k202CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
- IIROutputPorts, IComPorts
- {
- public DmTx4k202C Tx { get; private set; }
-
- public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
- public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
- public RoutingOutputPort DmOut { get; private set; }
- public RoutingOutputPort HdmiLoopOut { get; private set; }
-
- public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
- public IntFeedback VideoSourceNumericFeedback { get; protected set; }
- public IntFeedback AudioSourceNumericFeedback { get; protected set; }
- public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
- public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
- public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
+ public class DmTx4k202CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
+ IIROutputPorts, IComPorts
+ {
+ public DmTx4k202C Tx { get; private set; }
+
+ public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
+ public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
+ public RoutingOutputPort DmOut { get; private set; }
+ public RoutingOutputPort HdmiLoopOut { get; private set; }
+
+ public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
+ public IntFeedback VideoSourceNumericFeedback { get; protected set; }
+ public IntFeedback AudioSourceNumericFeedback { get; protected set; }
+ public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
+ public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
+ public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
//IroutingNumericEvent
@@ -50,50 +50,50 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
- }
-
-
- //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
- //public override ushort HdcpSupportCapability { get; protected set; }
-
- ///
- /// Helps get the "real" inputs, including when in Auto
- ///
- public Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType ActualActiveVideoInput
- {
- get
- {
- if (Tx.VideoSourceFeedback != eVst.Auto)
- return Tx.VideoSourceFeedback;
- else // auto
- {
- if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
- return eVst.Hdmi1;
- else if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
- return eVst.Hdmi2;
- else
- return eVst.AllDisabled;
- }
- }
- }
- public RoutingPortCollection InputPorts
- {
- get
- {
+ }
+
+
+ //public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
+ //public override ushort HdcpSupportCapability { get; protected set; }
+
+ ///
+ /// Helps get the "real" inputs, including when in Auto
+ ///
+ public Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType ActualActiveVideoInput
+ {
+ get
+ {
+ if (Tx.VideoSourceFeedback != eVst.Auto)
+ return Tx.VideoSourceFeedback;
+ else // auto
+ {
+ if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
+ return eVst.Hdmi1;
+ else if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
+ return eVst.Hdmi2;
+ else
+ return eVst.AllDisabled;
+ }
+ }
+ }
+ public RoutingPortCollection InputPorts
+ {
+ get
+ {
return new RoutingPortCollection
{
HdmiIn1,
HdmiIn2,
AnyVideoInput
- };
- }
- }
- public RoutingPortCollection OutputPorts
- {
- get
- {
- return new RoutingPortCollection { DmOut, HdmiLoopOut };
- }
+ };
+ }
+ }
+ public RoutingPortCollection OutputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection { DmOut, HdmiLoopOut };
+ }
}
public DmTx4k202CController(string key, string name, DmTx4k202C tx, bool preventRegistration)
@@ -127,28 +127,23 @@ namespace PepperDash.Essentials.DM
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);
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability",
- () => (int) tx.HdmiInputs[1].HdcpCapabilityFeedback);
+ () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability",
- () => (int) tx.HdmiInputs[2].HdcpCapabilityFeedback);
-
- HdcpStateFeedback =
- new IntFeedback(
- () =>
- tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
- ? (int) tx.HdmiInputs[1].HdcpCapabilityFeedback
- : (int) tx.HdmiInputs[2].HdcpCapabilityFeedback);
+ () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
- Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool) tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
+ HdcpStateFeedback = new IntFeedback(() => (int)HdcpSupportCapability);
- Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool) tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
+ Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
+
+ Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
var combinedFuncs = new VideoStatusFuncsWrapper
{
@@ -210,120 +205,120 @@ namespace PepperDash.Essentials.DM
- public override bool CustomActivate()
- {
- // Link up all of these damned events to the various RoutingPorts via a helper handler
- Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
- Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
-
- Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
- Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
-
- // Base does register and sets up comm monitoring.
- return base.CustomActivate();
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
-
- if (Hdmi1VideoSyncFeedback != null)
- {
- Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
- }
- if (Hdmi2VideoSyncFeedback != null)
- {
- Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
- }
-
- LinkDmTxToApi(this, trilist, joinMap, bridge);
- }
-
- public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
- {
- Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
-
- switch (type)
- {
- case eRoutingSignalType.Video:
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(eVst.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(HdmiIn1.Selector, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(HdmiIn2.Selector, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(eVst.AllDisabled, null, type);
- break;
- }
- }
- break;
- case eRoutingSignalType.Audio:
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(eAst.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(eAst.Hdmi1, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(eAst.Hdmi2, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(eAst.AllDisabled, null, type);
- break;
- }
- }
- break;
- }
- }
-
- public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
- {
- if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
- Tx.VideoSource = (eVst)inputSelector;
- if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
- Tx.AudioSource = (eAst)inputSelector;
- }
-
- void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
- Debug.Console(2, "{0} event {1} stream {2}", this.Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
-
- switch (args.EventId)
- {
- case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
- case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
- case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
- if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
- if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
- HdcpStateFeedback.FireUpdate();
- break;
- case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
- if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
- if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
- break;
- }
+ public override bool CustomActivate()
+ {
+ // Link up all of these damned events to the various RoutingPorts via a helper handler
+ Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
+ Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
+
+ Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
+ Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
+
+ // Base does register and sets up comm monitoring.
+ return base.CustomActivate();
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
+
+ if (Hdmi1VideoSyncFeedback != null)
+ {
+ Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
+ }
+ if (Hdmi2VideoSyncFeedback != null)
+ {
+ Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
+ }
+
+ LinkDmTxToApi(this, trilist, joinMap, bridge);
+ }
+
+ public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
+ {
+ Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
+
+ switch (type)
+ {
+ case eRoutingSignalType.Video:
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(eVst.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(HdmiIn1.Selector, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(HdmiIn2.Selector, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(eVst.AllDisabled, null, type);
+ break;
+ }
+ }
+ break;
+ case eRoutingSignalType.Audio:
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(eAst.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(eAst.Hdmi1, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(eAst.Hdmi2, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(eAst.AllDisabled, null, type);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
+ {
+ if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
+ Tx.VideoSource = (eVst)inputSelector;
+ if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
+ Tx.AudioSource = (eAst)inputSelector;
+ }
+
+ void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
+ {
+ Debug.Console(2, "{0} event {1} stream {2}", this.Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
+
+ switch (args.EventId)
+ {
+ case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
+ case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
+ case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
+ if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
+ if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
+ HdcpStateFeedback.FireUpdate();
+ break;
+ case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
+ if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
+ if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
+ break;
+ }
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
@@ -361,62 +356,62 @@ namespace PepperDash.Essentials.DM
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
- }
-
- ///
- /// Relays the input stream change to the appropriate RoutingInputPort.
- ///
- void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
- {
- return;
- }
- inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
- }
-
- ///
- /// Relays the VideoAttributes change to a RoutingInputPort
- ///
- void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
- //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
- // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
- switch (eventId)
- {
- case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
- inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HdcpStateFeedbackEventId:
- inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
- case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- }
- }
-
-
-
-
- #region IIROutputPorts Members
- public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
- public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
- #endregion
-
- #region IComPorts Members
- public CrestronCollection ComPorts { get { return Tx.ComPorts; } }
- public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
- #endregion
- }
+ }
+
+ ///
+ /// Relays the input stream change to the appropriate RoutingInputPort.
+ ///
+ void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
+ {
+ return;
+ }
+ inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
+ }
+
+ ///
+ /// Relays the VideoAttributes change to a RoutingInputPort
+ ///
+ void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
+ //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
+ // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
+ switch (eventId)
+ {
+ case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
+ inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HdcpStateFeedbackEventId:
+ inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
+ case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ }
+ }
+
+
+
+
+ #region IIROutputPorts Members
+ public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
+ public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
+ #endregion
+
+ #region IComPorts Members
+ public CrestronCollection ComPorts { get { return Tx.ComPorts; } }
+ public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs
index 87906735..0a5532bf 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4k302CController.cs
@@ -1,49 +1,49 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
-using Crestron.SimplSharpPro;
-//using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DeviceSupport;
-using Crestron.SimplSharpPro.DM;
-using Crestron.SimplSharpPro.DM.Endpoints;
-using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
-
-using PepperDash.Core;
-using PepperDash.Essentials.Core;
-using PepperDash.Essentials.Core.Bridges;
-using PepperDash.Essentials.DM.Config;
-
-namespace PepperDash.Essentials.DM
-{
- using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Crestron.SimplSharp;
+using Crestron.SimplSharpPro;
+//using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DeviceSupport;
+using Crestron.SimplSharpPro.DM;
+using Crestron.SimplSharpPro.DM.Endpoints;
+using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
+
+using PepperDash.Core;
+using PepperDash.Essentials.Core;
+using PepperDash.Essentials.Core.Bridges;
+using PepperDash.Essentials.DM.Config;
+
+namespace PepperDash.Essentials.DM
+{
+ using eVst = Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType;
using eAst = Crestron.SimplSharpPro.DeviceSupport.eX02AudioSourceType;
[Description("Wrapper class for DM-TX-4K-302-C")]
- public class DmTx4k302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
- IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
- {
- public DmTx4k302C Tx { get; private set; }
-
- public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
- public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
- public RoutingInputPortWithVideoStatuses VgaIn { get; private set; }
- public RoutingOutputPort DmOut { get; private set; }
- public RoutingOutputPort HdmiLoopOut { get; private set; }
-
- public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
- public IntFeedback VideoSourceNumericFeedback { get; protected set; }
- public IntFeedback AudioSourceNumericFeedback { get; protected set; }
- public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
- public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
- public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
- public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
- public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
-
- public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
-
- public IntFeedback VgaBrightnessFeedback { get; protected set; }
+ public class DmTx4k302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
+ IIROutputPorts, IComPorts, IHasFreeRun, IVgaBrightnessContrastControls
+ {
+ public DmTx4k302C Tx { get; private set; }
+
+ public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
+ public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
+ public RoutingInputPortWithVideoStatuses VgaIn { get; private set; }
+ public RoutingOutputPort DmOut { get; private set; }
+ public RoutingOutputPort HdmiLoopOut { get; private set; }
+
+ public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
+ public IntFeedback VideoSourceNumericFeedback { get; protected set; }
+ public IntFeedback AudioSourceNumericFeedback { get; protected set; }
+ public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
+ public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
+ public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
+ public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
+ public BoolFeedback VgaVideoSyncFeedback { get; protected set; }
+
+ public BoolFeedback FreeRunEnabledFeedback { get; protected set; }
+
+ public IntFeedback VgaBrightnessFeedback { get; protected set; }
public IntFeedback VgaContrastFeedback { get; protected set; }
//IroutingNumericEvent
@@ -57,171 +57,166 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
- }
-
-
- ///
- /// Helps get the "real" inputs, including when in Auto
- ///
- public Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType ActualActiveVideoInput
- {
- get
- {
- if (Tx.VideoSourceFeedback != eVst.Auto)
- return Tx.VideoSourceFeedback;
- else // auto
- {
- if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
- return eVst.Hdmi1;
- else if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
- return eVst.Hdmi2;
- else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue)
- return eVst.Vga;
- else
- return eVst.AllDisabled;
- }
- }
- }
- public RoutingPortCollection InputPorts
- {
- get
- {
- return new RoutingPortCollection
- {
- HdmiIn1,
- HdmiIn2,
- VgaIn,
- AnyVideoInput
- };
- }
- }
- public RoutingPortCollection OutputPorts
- {
- get
- {
- return new RoutingPortCollection { DmOut, HdmiLoopOut };
- }
- }
- public DmTx4k302CController(string key, string name, DmTx4k302C tx, bool preventRegistration)
- : base(key, name, tx)
- {
- Tx = tx;
- PreventRegistration = preventRegistration;
-
- HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
- VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
- {
- FeedbackMatchObject = eVst.Hdmi1
- };
- HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
- VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
+ }
+
+
+ ///
+ /// Helps get the "real" inputs, including when in Auto
+ ///
+ public Crestron.SimplSharpPro.DeviceSupport.eX02VideoSourceType ActualActiveVideoInput
+ {
+ get
+ {
+ if (Tx.VideoSourceFeedback != eVst.Auto)
+ return Tx.VideoSourceFeedback;
+ else // auto
+ {
+ if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
+ return eVst.Hdmi1;
+ else if (Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
+ return eVst.Hdmi2;
+ else if (Tx.VgaInput.SyncDetectedFeedback.BoolValue)
+ return eVst.Vga;
+ else
+ return eVst.AllDisabled;
+ }
+ }
+ }
+ public RoutingPortCollection InputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection
+ {
+ HdmiIn1,
+ HdmiIn2,
+ VgaIn,
+ AnyVideoInput
+ };
+ }
+ }
+ public RoutingPortCollection OutputPorts
+ {
+ get
+ {
+ return new RoutingPortCollection { DmOut, HdmiLoopOut };
+ }
+ }
+ public DmTx4k302CController(string key, string name, DmTx4k302C tx, bool preventRegistration)
+ : base(key, name, tx)
+ {
+ Tx = tx;
+ PreventRegistration = preventRegistration;
+
+ HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,
+ VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[1]))
+ {
+ FeedbackMatchObject = eVst.Hdmi1
+ };
+ HdmiIn2 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn2,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi2, this,
+ VideoStatusHelper.GetHdmiInputStatusFuncs(tx.HdmiInputs[2]))
{
FeedbackMatchObject = eVst.Hdmi2
};
-
- VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
- eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.Vga, this,
- VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
+
+ VgaIn = new RoutingInputPortWithVideoStatuses(DmPortName.VgaIn,
+ eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, eVst.Vga, this,
+ VideoStatusHelper.GetVgaInputStatusFuncs(tx.VgaInput))
{
FeedbackMatchObject = eVst.Vga
};
-
- ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
- () => ActualActiveVideoInput.ToString());
-
- Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
+
+ ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
+ () => ActualActiveVideoInput.ToString());
+
+ Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
- Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
- Tx.BaseEvent += Tx_BaseEvent;
-
- Tx.OnlineStatusChange += Tx_OnlineStatusChange;
-
- VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
- AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
-
- HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
-
+ Tx.VgaInput.InputStreamChange += VgaInputOnInputStreamChange;
+ Tx.BaseEvent += Tx_BaseEvent;
+
+ Tx.OnlineStatusChange += Tx_OnlineStatusChange;
+
+ VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
+ AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.AudioSourceFeedback);
+
+ HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
+
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
- HdcpStateFeedback =
- new IntFeedback(
- () =>
- tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
- ? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback
- : (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
-
- HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
-
- Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
-
- Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
-
- VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue);
-
- FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
-
- VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
- VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
-
- tx.VgaInput.VideoControls.ControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(VideoControls_ControlChange);
-
-
- var combinedFuncs = new VideoStatusFuncsWrapper
- {
- HdcpActiveFeedbackFunc = () =>
- (ActualActiveVideoInput == eVst.Hdmi1
- && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
- || (ActualActiveVideoInput == eVst.Hdmi2
- && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
-
- HdcpStateFeedbackFunc = () =>
- {
- if (ActualActiveVideoInput == eVst.Hdmi1)
- return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
- return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
- },
-
- VideoResolutionFeedbackFunc = () =>
- {
- if (ActualActiveVideoInput == eVst.Hdmi1)
- return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
- if (ActualActiveVideoInput == eVst.Hdmi2)
- return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
- return ActualActiveVideoInput == eVst.Vga ? tx.VgaInput.VideoAttributes.GetVideoResolutionString() : "";
- },
- VideoSyncFeedbackFunc = () =>
- (ActualActiveVideoInput == eVst.Hdmi1
- && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == eVst.Hdmi2
- && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
- || (ActualActiveVideoInput == eVst.Vga
- && tx.VgaInput.SyncDetectedFeedback.BoolValue)
-
- };
-
- AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
- eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
-
- DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.DmCat, null, this);
- HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
- eRoutingPortConnectionType.Hdmi, null, this);
-
-
- AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
- AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
- AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
- AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
- Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, VgaVideoSyncFeedback);
-
- // Set Ports for CEC
- HdmiIn1.Port = Tx.HdmiInputs[1];
- HdmiIn2.Port = Tx.HdmiInputs[2];
- HdmiLoopOut.Port = Tx.HdmiOutput;
- DmOut.Port = Tx.DmOutput;
- }
+ HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
+
+ HdcpStateFeedback = new IntFeedback(() => (int)HdcpSupportCapability);
+
+ Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
+
+ Hdmi2VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue);
+
+ VgaVideoSyncFeedback = new BoolFeedback(() => (bool)tx.VgaInput.SyncDetectedFeedback.BoolValue);
+
+ FreeRunEnabledFeedback = new BoolFeedback(() => tx.VgaInput.FreeRunFeedback == eDmFreeRunSetting.Enabled);
+
+ VgaBrightnessFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.BrightnessFeedback.UShortValue);
+ VgaContrastFeedback = new IntFeedback(() => tx.VgaInput.VideoControls.ContrastFeedback.UShortValue);
+
+ tx.VgaInput.VideoControls.ControlChange += new Crestron.SimplSharpPro.DeviceSupport.GenericEventHandler(VideoControls_ControlChange);
+
+
+ var combinedFuncs = new VideoStatusFuncsWrapper
+ {
+ HdcpActiveFeedbackFunc = () =>
+ (ActualActiveVideoInput == eVst.Hdmi1
+ && tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.Hdmi2
+ && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
+
+ HdcpStateFeedbackFunc = () =>
+ {
+ if (ActualActiveVideoInput == eVst.Hdmi1)
+ return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
+ return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
+ },
+
+ VideoResolutionFeedbackFunc = () =>
+ {
+ if (ActualActiveVideoInput == eVst.Hdmi1)
+ return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
+ if (ActualActiveVideoInput == eVst.Hdmi2)
+ return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
+ return ActualActiveVideoInput == eVst.Vga ? tx.VgaInput.VideoAttributes.GetVideoResolutionString() : "";
+ },
+ VideoSyncFeedbackFunc = () =>
+ (ActualActiveVideoInput == eVst.Hdmi1
+ && tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.Hdmi2
+ && tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.Vga
+ && tx.VgaInput.SyncDetectedFeedback.BoolValue)
+
+ };
+
+ AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
+ eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
+
+ DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.DmCat, null, this);
+ HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
+ eRoutingPortConnectionType.Hdmi, null, this);
+
+
+ AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
+ AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
+ AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
+ AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
+ Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, VgaVideoSyncFeedback);
+
+ // Set Ports for CEC
+ HdmiIn1.Port = Tx.HdmiInputs[1];
+ HdmiIn2.Port = Tx.HdmiInputs[2];
+ HdmiLoopOut.Port = Tx.HdmiOutput;
+ DmOut.Port = Tx.DmOutput;
+ }
void VgaInputOnInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{
@@ -234,13 +229,13 @@ namespace PepperDash.Essentials.DM
VgaVideoSyncFeedback.FireUpdate();
break;
}
- }
-
- void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
- {
- var id = args.EventId;
- Debug.Console(2, this, "EventId {0}", args.EventId);
-
+ }
+
+ void VideoControls_ControlChange(object sender, Crestron.SimplSharpPro.DeviceSupport.GenericEventArgs args)
+ {
+ var id = args.EventId;
+ Debug.Console(2, this, "EventId {0}", args.EventId);
+
switch (id)
{
case VideoControlsEventIds.BrightnessFeedbackEventId:
@@ -249,76 +244,76 @@ namespace PepperDash.Essentials.DM
case VideoControlsEventIds.ContrastFeedbackEventId:
VgaContrastFeedback.FireUpdate();
break;
- }
- }
-
-
-
- public override bool CustomActivate()
- {
- // Link up all of these damned events to the various RoutingPorts via a helper handler
- Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
- Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
-
- Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
- Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
-
- Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaIn, a.EventId);
- Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(VgaIn, a.EventId);
-
- // Base does register and sets up comm monitoring.
- return base.CustomActivate();
- }
-
- public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
- {
- var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
-
- if (Hdmi1VideoSyncFeedback != null)
+ }
+ }
+
+
+
+ public override bool CustomActivate()
+ {
+ // Link up all of these damned events to the various RoutingPorts via a helper handler
+ Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
+ Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
+
+ Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
+ Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
+
+ Tx.VgaInput.InputStreamChange += (o, a) => FowardInputStreamChange(VgaIn, a.EventId);
+ Tx.VgaInput.VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(VgaIn, a.EventId);
+
+ // Base does register and sets up comm monitoring.
+ return base.CustomActivate();
+ }
+
+ public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
+ {
+ var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
+
+ if (Hdmi1VideoSyncFeedback != null)
{
- Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
- }
- if (Hdmi2VideoSyncFeedback != null)
+ Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
+ }
+ if (Hdmi2VideoSyncFeedback != null)
{
- Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
- }
- if (VgaVideoSyncFeedback != null)
+ Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
+ }
+ if (VgaVideoSyncFeedback != null)
{
- VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]);
- }
-
- LinkDmTxToApi(this, trilist, joinMap, bridge);
- }
-
- ///
- /// Enables or disables free run
- ///
- ///
+ VgaVideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input3VideoSyncStatus.JoinNumber]);
+ }
+
+ LinkDmTxToApi(this, trilist, joinMap, bridge);
+ }
+
+ ///
+ /// Enables or disables free run
+ ///
+ ///
public void SetFreeRunEnabled(bool enable)
{
Tx.VgaInput.FreeRun = enable ? eDmFreeRunSetting.Enabled : eDmFreeRunSetting.Disabled;
}
- ///
- /// Sets the VGA brightness level
- ///
- ///
- public void SetVgaBrightness(ushort level)
- {
- Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
- }
-
- ///
- /// Sets the VGA contrast level
- ///
- ///
- public void SetVgaContrast(ushort level)
- {
- Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
- }
-
-
-
+ ///
+ /// Sets the VGA brightness level
+ ///
+ ///
+ public void SetVgaBrightness(ushort level)
+ {
+ Tx.VgaInput.VideoControls.Brightness.UShortValue = level;
+ }
+
+ ///
+ /// Sets the VGA contrast level
+ ///
+ ///
+ public void SetVgaContrast(ushort level)
+ {
+ Tx.VgaInput.VideoControls.Contrast.UShortValue = level;
+ }
+
+
+
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
@@ -326,76 +321,76 @@ namespace PepperDash.Essentials.DM
switch (type)
{
case eRoutingSignalType.Video:
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(eVst.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(HdmiIn1.Selector, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(HdmiIn2.Selector, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(VgaIn.Selector, null, type);
- break;
- }
- case 4:
- {
- ExecuteSwitch(eVst.AllDisabled, null, type);
- break;
- }
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(eVst.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(HdmiIn1.Selector, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(HdmiIn2.Selector, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(VgaIn.Selector, null, type);
+ break;
+ }
+ case 4:
+ {
+ ExecuteSwitch(eVst.AllDisabled, null, type);
+ break;
+ }
}
break;
case eRoutingSignalType.Audio:
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(eAst.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(eAst.Hdmi1, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(eAst.Hdmi2, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(eAst.AudioIn, null, type);
- break;
- }
- case 4:
- {
- ExecuteSwitch(eAst.AllDisabled, null, type);
- break;
- }
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(eAst.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(eAst.Hdmi1, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(eAst.Hdmi2, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(eAst.AudioIn, null, type);
+ break;
+ }
+ case 4:
+ {
+ ExecuteSwitch(eAst.AllDisabled, null, type);
+ break;
+ }
}
break;
}
}
- public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
- {
- if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
- Tx.VideoSource = (eVst)inputSelector;
- if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
- Tx.AudioSource = (eAst)inputSelector;
- }
-
+ public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
+ {
+ if ((signalType | eRoutingSignalType.Video) == eRoutingSignalType.Video)
+ Tx.VideoSource = (eVst)inputSelector;
+ if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
+ Tx.AudioSource = (eAst)inputSelector;
+ }
+
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{
Debug.Console(2, "{0} event {1} stream {2}", this.Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
@@ -405,7 +400,7 @@ namespace PepperDash.Essentials.DM
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
- if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
+ if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
HdcpStateFeedback.FireUpdate();
break;
@@ -450,57 +445,57 @@ namespace PepperDash.Essentials.DM
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
- }
+ }
- ///
- /// Relays the input stream change to the appropriate RoutingInputPort.
- ///
- void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
+ ///
+ /// Relays the input stream change to the appropriate RoutingInputPort.
+ ///
+ void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId) return;
- inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
+ inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
- }
-
- ///
- /// Relays the VideoAttributes change to a RoutingInputPort
- ///
- void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
- {
- //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
- //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
- // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
- switch (eventId)
- {
- case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
- inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HdcpStateFeedbackEventId:
- inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
- case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
- inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
- AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
- break;
- }
- }
-
-
- #region IIROutputPorts Members
- public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
- public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
- #endregion
-
- #region IComPorts Members
- public CrestronCollection ComPorts { get { return Tx.ComPorts; } }
- public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
- #endregion
- }
-}
\ No newline at end of file
+ }
+
+ ///
+ /// Relays the VideoAttributes change to a RoutingInputPort
+ ///
+ void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
+ {
+ //// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
+ //Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
+ // args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
+ switch (eventId)
+ {
+ case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
+ inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HdcpStateFeedbackEventId:
+ inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
+ case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
+ inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
+ break;
+ }
+ }
+
+
+ #region IIROutputPorts Members
+ public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
+ public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
+ #endregion
+
+ #region IComPorts Members
+ public CrestronCollection ComPorts { get { return Tx.ComPorts; } }
+ public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz100Controller.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz100Controller.cs
index c1a5cec7..bb7d9e3d 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz100Controller.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz100Controller.cs
@@ -72,6 +72,7 @@ namespace PepperDash.Essentials.DM
HdmiIn.Port = Tx;
PreventRegistration = true;
+ tx.Register();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs
index de60d80e..bd74bf5a 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTx4kz302CController.cs
@@ -18,7 +18,7 @@ namespace PepperDash.Essentials.DM
[Description("Wrapper class for DM-TX-4K-Z-302-C")]
- public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback, IHasFeedback,
+ public class DmTx4kz302CController : DmTxControllerBase, ITxRoutingWithFeedback,
IIROutputPorts, IComPorts
{
public DmTx4kz302C Tx { get; private set; }
@@ -34,6 +34,7 @@ namespace PepperDash.Essentials.DM
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
+ public IntFeedback DisplayPortInHdcpCapabilityFeedback { get; protected set; }
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
public BoolFeedback DisplayPortVideoSyncFeedback { get; protected set; }
@@ -120,7 +121,7 @@ namespace PepperDash.Essentials.DM
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
- Tx.DisplayPortInput.InputStreamChange += DisplayPortInputStreamChange;
+ Tx.DisplayPortInput.InputStreamChange += InputStreamChangeEvent;
Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
@@ -130,15 +131,32 @@ namespace PepperDash.Essentials.DM
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
+ DisplayPortInHdcpCapabilityFeedback = new IntFeedback("DisplayPortInHdcpCapability",
+ () => (int)tx.DisplayPortInput.HdcpCapabilityFeedback);
+
+ /*
HdcpStateFeedback =
new IntFeedback(
() =>
tx.HdmiInputs[1].HdcpCapabilityFeedback > tx.HdmiInputs[2].HdcpCapabilityFeedback
? (int)tx.HdmiInputs[1].HdcpCapabilityFeedback
: (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
+ */
+
+ //yeah this is gross - but it's the quickest way to do this...
+ /*
+ HdcpStateFeedback = new IntFeedback(() => {
+ var states = new[] {(int) tx.DisplayPortInput.HdcpCapabilityFeedback, (int) tx.HdmiInputs[1].HdcpCapabilityFeedback, (int) tx.HdmiInputs[2].HdcpCapabilityFeedback};
+
+ return states.Max();
+ });
+ */
HdcpSupportCapability = eHdcpCapabilityType.Hdcp2_2Support;
+ // I feel like we have had this as a misnomer for so long, that it really needed to be fixed
+ // All we were doing was reporting the best of the current statuses - not the actual capability of the device.
+ HdcpStateFeedback = new IntFeedback(() => (int)HdcpSupportCapability);
Hdmi1VideoSyncFeedback = new BoolFeedback(() => (bool)tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue);
@@ -146,20 +164,25 @@ namespace PepperDash.Essentials.DM
DisplayPortVideoSyncFeedback = new BoolFeedback(() => (bool)tx.DisplayPortInput.SyncDetectedFeedback.BoolValue);
-
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
(ActualActiveVideoInput == eVst.Hdmi1
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
- && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
+ && tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.DisplayPort
+ && tx.DisplayPortInput.VideoAttributes.HdcpActiveFeedback.BoolValue),
HdcpStateFeedbackFunc = () =>
{
if (ActualActiveVideoInput == eVst.Hdmi1)
- return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
- return ActualActiveVideoInput == eVst.Hdmi2 ? tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString() : "";
+ return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
+ if (ActualActiveVideoInput == eVst.Hdmi2)
+ return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
+ return ActualActiveVideoInput == eVst.DisplayPort
+ ? tx.DisplayPortInput.VideoAttributes.HdcpStateFeedback.ToString()
+ : "";
},
VideoResolutionFeedbackFunc = () =>
@@ -168,6 +191,8 @@ namespace PepperDash.Essentials.DM
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
if (ActualActiveVideoInput == eVst.Hdmi2)
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
+ if (ActualActiveVideoInput == eVst.DisplayPort)
+ return tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString();
return ActualActiveVideoInput == eVst.Vga ? tx.DisplayPortInput.VideoAttributes.GetVideoResolutionString() : "";
},
VideoSyncFeedbackFunc = () =>
@@ -175,6 +200,8 @@ namespace PepperDash.Essentials.DM
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
+ || (ActualActiveVideoInput == eVst.DisplayPort
+ && tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Vga
&& tx.DisplayPortInput.SyncDetectedFeedback.BoolValue)
@@ -193,28 +220,15 @@ namespace PepperDash.Essentials.DM
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
- Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback);
+ Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback, DisplayPortVideoSyncFeedback, DisplayPortInHdcpCapabilityFeedback);
- // Set Ports for CEC
HdmiIn1.Port = Tx.HdmiInputs[1];
HdmiIn2.Port = Tx.HdmiInputs[2];
+ DisplayPortIn.Port = Tx.DisplayPortInput;
HdmiLoopOut.Port = Tx.HdmiOutput;
DmOut.Port = Tx.DmOutput;
}
- void DisplayPortInputStreamChange(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
- {
- Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
-
- switch (args.EventId)
- {
- case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
- DisplayPortVideoSyncFeedback.FireUpdate();
- break;
- }
- }
-
-
public override bool CustomActivate()
{
@@ -256,41 +270,41 @@ namespace PepperDash.Essentials.DM
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
- switch (input)
- {
- case 0:
- {
- ExecuteSwitch(eVst.Auto, null, type);
- break;
- }
- case 1:
- {
- ExecuteSwitch(HdmiIn1.Selector, null, type);
- break;
- }
- case 2:
- {
- ExecuteSwitch(HdmiIn2.Selector, null, type);
- break;
- }
- case 3:
- {
- ExecuteSwitch(DisplayPortIn.Selector, null, type);
- break;
- }
- case 4:
- {
- ExecuteSwitch(eVst.AllDisabled, null, type);
- break;
- }
- default:
+ switch (input)
+ {
+ case 0:
+ {
+ ExecuteSwitch(eVst.Auto, null, type);
+ break;
+ }
+ case 1:
+ {
+ ExecuteSwitch(HdmiIn1.Selector, null, type);
+ break;
+ }
+ case 2:
+ {
+ ExecuteSwitch(HdmiIn2.Selector, null, type);
+ break;
+ }
+ case 3:
+ {
+ ExecuteSwitch(DisplayPortIn.Selector, null, type);
+ break;
+ }
+ case 4:
+ {
+ ExecuteSwitch(eVst.AllDisabled, null, type);
+ break;
+ }
+ default:
{
Debug.Console(2, this, "Unable to execute numeric switch to input {0}", input);
break;
}
- }
-
+ }
+
}
@@ -326,11 +340,17 @@ namespace PepperDash.Essentials.DM
case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
+ if (inputStream == Tx.DisplayPortInput) DisplayPortInHdcpCapabilityFeedback.FireUpdate();
+
+ Debug.Console(2, this, "DisplayPortHDCP Mode Trigger = {0}",
+ DisplayPortInHdcpCapabilityFeedback.IntValue);
+
HdcpStateFeedback.FireUpdate();
break;
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
+ if (inputStream == Tx.DisplayPortInput) DisplayPortVideoSyncFeedback.FireUpdate();
break;
}
}
@@ -413,7 +433,6 @@ namespace PepperDash.Essentials.DM
}
}
-
#region IIROutputPorts Members
public CrestronCollection IROutputPorts { get { return Tx.IROutputPorts; } }
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs
index d707ebd3..140f0f45 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/DmTxHelpers.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
@@ -18,8 +16,8 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM
{
- public class DmTxHelper
- {
+ public class DmTxHelper
+ {
public static BasicDmTxControllerBase GetDmTxForChassisWithoutIpId(string key, string name, string typeName, DMInput dmInput)
{
@@ -44,7 +42,7 @@ namespace PepperDash.Essentials.DM
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(dmInput), true);
if (typeName.StartsWith("hdbasettx"))
- new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
+ return new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
return null;
}
@@ -77,31 +75,32 @@ namespace PepperDash.Essentials.DM
return null;
}
- ///
- /// A factory method for various DmTxControllers
- ///
- ///
- ///
- ///
- ///
+ ///
+ /// A factory method for various DmTxControllers
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public static BasicDmTxControllerBase GetDmTxController(string key, string name, string typeName, DmTxPropertiesConfig props)
- {
- // switch on type name... later...
+ {
+ // switch on type name... later...
- typeName = typeName.ToLower();
- //uint ipid = Convert.ToUInt16(props.Id, 16);
- var ipid = props.Control.IpIdInt;
- var pKey = props.ParentDeviceKey.ToLower();
+ typeName = typeName.ToLower();
+ //uint ipid = Convert.ToUInt16(props.Id, 16);
+ var ipid = props.Control.IpIdInt;
+ var pKey = props.ParentDeviceKey.ToLower();
if (pKey == "processor")
- {
- // Catch constructor failures, mainly dues to IPID
- try
- {
- if(typeName.StartsWith("dmtx200"))
+ {
+ // Catch constructor failures, mainly dues to IPID
+ try
+ {
+ if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem), false);
- if (typeName.StartsWith("dmtx201c"))
- return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem), false);
+ if (typeName.StartsWith("dmtx201c"))
+ return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4k202"))
@@ -112,35 +111,36 @@ namespace PepperDash.Essentials.DM
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem), false);
- if (typeName.StartsWith("dmtx401"))
+ if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem), false);
- Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key);
- }
- catch (Exception e)
- {
- Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
- }
+ Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key);
+ }
+ catch (Exception e)
+ {
+ Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
+ }
return null;
- }
+ }
var parentDev = DeviceManager.GetDeviceForKey(pKey);
DMInput dmInput;
BasicDmTxControllerBase tx;
+ bool useChassisForOfflineFeedback = false;
- if (parentDev is DmChassisController)
+ if (parentDev is IDmSwitchWithEndpointOnlineFeedback)
{
// Get the Crestron chassis and link stuff up
- var switchDev = (parentDev as DmChassisController);
- var chassis = switchDev.Chassis;
+ var switchDev = (parentDev as IDmSwitchWithEndpointOnlineFeedback);
+ var chassis = switchDev.Chassis;
//Check that the input is within range of this chassis' possible inputs
- var num = props.ParentInputNumber;
- if (num <= 0 || num > chassis.NumberOfInputs)
- {
- Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
- key, num);
- return null;
- }
+ var num = props.ParentInputNumber;
+ if (num <= 0 || num > chassis.NumberOfInputs)
+ {
+ Debug.Console(0, "Cannot create DM device '{0}'. Input number '{1}' is out of range",
+ key, num);
+ return null;
+ }
switchDev.TxDictionary.Add(num, key);
dmInput = chassis.Inputs[num];
@@ -155,15 +155,23 @@ namespace PepperDash.Essentials.DM
chassis is DmMd128x128 || chassis is DmMd64x64)
{
tx = GetDmTxForChassisWithoutIpId(key, name, typeName, dmInput);
- Debug.Console(0, "DM endpoint output {0} is for Cpu3, changing online feedback to chassis", num);
- tx.IsOnline.SetValueFunc(() => switchDev.InputEndpointOnlineFeedbacks[num].BoolValue);
- switchDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
- return tx;
+ useChassisForOfflineFeedback = true;
}
else
{
- return GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
+ tx = GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
+ if (typeName == "hdbasettx" || typeName == "dmtx4k100c1g")
+ {
+ useChassisForOfflineFeedback = true;
+ }
}
+ if (useChassisForOfflineFeedback)
+ {
+ Debug.Console(0, "DM endpoint output {0} does not have direct online feedback, changing online feedback to chassis", num);
+ tx.IsOnline.SetValueFunc(() => switchDev.InputEndpointOnlineFeedbacks[num].BoolValue);
+ switchDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
+ }
+ return tx;
}
catch (Exception e)
{
@@ -171,7 +179,8 @@ namespace PepperDash.Essentials.DM
return null;
}
}
- else if(parentDev is DmpsRoutingController)
+
+ if (parentDev is DmpsRoutingController)
{
// Get the DMPS chassis and link stuff up
var dmpsDev = (parentDev as DmpsRoutingController);
@@ -200,33 +209,38 @@ namespace PepperDash.Essentials.DM
try
{
- if(Global.ControlSystemIsDmps4kType)
+ if (Global.ControlSystemIsDmps4kType)
{
tx = GetDmTxForChassisWithoutIpId(key, name, typeName, dmInput);
- Debug.Console(0, "DM endpoint output {0} is for DMPS3-4K, changing online feedback to chassis", num);
- tx.IsOnline.SetValueFunc(() => dmpsDev.InputEndpointOnlineFeedbacks[num].BoolValue);
- dmpsDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
- return tx;
+ useChassisForOfflineFeedback = true;
}
else
{
- return GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
+ tx = GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
+ if (typeName == "hdbasettx" || typeName == "dmtx4k100c1g")
+ {
+ useChassisForOfflineFeedback = true;
+ }
}
+ if (useChassisForOfflineFeedback)
+ {
+ Debug.Console(0, "DM endpoint output {0} does not have direct online feedback, changing online feedback to chassis", num);
+ tx.IsOnline.SetValueFunc(() => dmpsDev.InputEndpointOnlineFeedbacks[num].BoolValue);
+ dmpsDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
+ }
+ return tx;
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device for dmps: {1}", key, e);
return null;
- }
+ }
}
- else
- {
- Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey);
- return null;
- }
- }
- }
+ Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey);
+ return null;
+ }
+ }
public abstract class BasicDmTxControllerBase : CrestronGenericBridgeableBaseDevice
{
@@ -237,21 +251,21 @@ namespace PepperDash.Essentials.DM
}
}
- ///
- ///
- ///
+ ///
+ ///
+ ///
[Description("Wrapper class for all DM-TX variants")]
- public abstract class DmTxControllerBase : BasicDmTxControllerBase
- {
+ public abstract class DmTxControllerBase : BasicDmTxControllerBase
+ {
public virtual void SetPortHdcpCapability(eHdcpCapabilityType hdcpMode, uint port) { }
public virtual eHdcpCapabilityType HdcpSupportCapability { get; protected set; }
public abstract StringFeedback ActiveVideoInputFeedback { get; protected set; }
public RoutingInputPortWithVideoStatuses AnyVideoInput { get; protected set; }
public IntFeedback HdcpStateFeedback { get; protected set; }
- protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
- : base(key, name, hardware)
- {
+ protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
+ : base(key, name, hardware)
+ {
AddToFeedbackList(ActiveVideoInputFeedback);
IsOnline.OutputChange += (currentDevice, args) =>
@@ -262,11 +276,12 @@ namespace PepperDash.Essentials.DM
feedback.FireUpdate();
}
};
- }
+ }
- protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware)
- {
- }
+ protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware)
+ : base(key, name, hardware)
+ {
+ }
protected DmTxControllerJoinMap GetDmTxJoinMap(uint joinStart, string joinMapKey)
{
@@ -280,8 +295,8 @@ namespace PepperDash.Essentials.DM
return joinMap;
}
- protected void LinkDmTxToApi(DmTxControllerBase tx, BasicTriList trilist, DmTxControllerJoinMap joinMap, EiscApiAdvanced bridge)
- {
+ protected void LinkDmTxToApi(DmTxControllerBase tx, BasicTriList trilist, DmTxControllerJoinMap joinMap, EiscApiAdvanced bridge)
+ {
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
@@ -291,7 +306,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
- Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
+ Debug.Console(1, tx, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
tx.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
tx.AnyVideoInput.VideoStatus.VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber]);
@@ -318,8 +333,6 @@ namespace PepperDash.Essentials.DM
txR.VideoSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.VideoInput.JoinNumber]);
txR.AudioSourceNumericFeedback.LinkInputSig(trilist.UShortInput[joinMap.AudioInput.JoinNumber]);
- trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber].UShortValue = (ushort)tx.HdcpSupportCapability;
-
if (txR.InputPorts[DmPortName.HdmiIn] != null)
{
var inputPort = txR.InputPorts[DmPortName.HdmiIn];
@@ -366,7 +379,7 @@ namespace PepperDash.Essentials.DM
{
var intFeedback = tx.Feedbacks["HdmiIn2HdcpCapability"] as IntFeedback;
if (intFeedback != null)
- intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port1HdcpState.JoinNumber]);
+ intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port2HdcpState.JoinNumber]);
}
if (inputPort.ConnectionType == eRoutingPortConnectionType.Hdmi && inputPort.Port != null)
@@ -377,6 +390,40 @@ namespace PepperDash.Essentials.DM
}
}
+ if (txR.InputPorts[DmPortName.DisplayPortIn] != null)
+ {
+ var inputPort = txR.InputPorts[DmPortName.DisplayPortIn];
+
+ if (tx.Feedbacks["DisplayPortInHdcpCapability"] != null)
+ {
+
+ var intFeedback = tx.Feedbacks["DisplayPortInHdcpCapability"] as IntFeedback;
+ if (intFeedback != null)
+
+ intFeedback.LinkInputSig(trilist.UShortInput[joinMap.Port3HdcpState.JoinNumber]);
+
+ if (inputPort.ConnectionType == eRoutingPortConnectionType.DisplayPort && inputPort.Port != null)
+ {
+ var port = inputPort.Port as EndpointDisplayPortInput;
+ SetHdcpCapabilityAction(port, joinMap.Port3HdcpState.JoinNumber, trilist);
+ }
+ }
+ }
+
+
+ var hdcpInputPortCount =
+ (ushort)
+ txR.InputPorts.Where(
+ x => (x.Type == eRoutingSignalType.Video) || (x.Type == eRoutingSignalType.AudioVideo))
+ .Where(
+ x =>
+ (x.ConnectionType == eRoutingPortConnectionType.DmCat) ||
+ (x.ConnectionType == eRoutingPortConnectionType.Hdmi) ||
+ (x.ConnectionType == eRoutingPortConnectionType.DisplayPort))
+ .ToList().Count();
+
+ trilist.SetUshort(joinMap.HdcpInputPortCount.JoinNumber, hdcpInputPortCount);
+
}
var txFreeRun = tx as IHasFreeRun;
@@ -416,7 +463,7 @@ namespace PepperDash.Essentials.DM
});
}
else
- {
+ {
trilist.SetUShortSigAction(join,
s =>
{
@@ -424,14 +471,40 @@ namespace PepperDash.Essentials.DM
});
}
}
- }
+
+ private void SetHdcpCapabilityAction(EndpointDisplayPortInput port, uint join,
+ BasicTriList trilist)
+ {
+ trilist.SetUShortSigAction(join,
+ s =>
+ {
+ Debug.Console(0, this, "Trying to set HDCP to {0} on port {1}", s, port.ToString());
+ port.HdcpCapability = (eHdcpCapabilityType) s;
+ });
+ }
+
+ }
public class DmTxControllerFactory : EssentialsDeviceFactory
{
public DmTxControllerFactory()
{
- TypeNames = new List() { "dmtx200c", "dmtx201c", "dmtx201s", "dmtx4k100c", "dmtx4k202c", "dmtx4kz202c", "dmtx4k302c", "dmtx4kz302c",
- "dmtx401c", "dmtx401s", "dmtx4k100c1g", "dmtx4kz100c1g", "hdbasettx" };
+ TypeNames = new List
+ {
+ "dmtx200c",
+ "dmtx201c",
+ "dmtx201s",
+ "dmtx4k100c",
+ "dmtx4k202c",
+ "dmtx4kz202c",
+ "dmtx4k302c",
+ "dmtx4kz302c",
+ "dmtx401c",
+ "dmtx401s",
+ "dmtx4k100c1g",
+ "dmtx4kz100c1g",
+ "hdbasettx"
+ };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
@@ -441,8 +514,8 @@ namespace PepperDash.Essentials.DM
Debug.Console(1, "Factory Attempting to create new DM-TX Device");
var props = JsonConvert.DeserializeObject
- (dc.Properties.ToString());
- return PepperDash.Essentials.DM.DmTxHelper.GetDmTxController(dc.Key, dc.Name, type, props);
+ (dc.Properties.ToString());
+ return DmTxHelper.GetDmTxController(dc.Key, dc.Name, type, props);
}
}
diff --git a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs
index bedf1aad..a40ee68b 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/Endpoints/Transmitters/HDBaseTTxController.cs
@@ -52,6 +52,9 @@ namespace PepperDash.Essentials.DM
IsOnline.SetValueFunc(() => controller.InputEndpointOnlineFeedbacks[num].BoolValue);
controller.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
+
+ PreventRegistration = true;
+ tx.Register();
}
#region IRoutingInputs Members
diff --git a/essentials-framework/Essentials DM/Essentials_DM/IDmSwitch.cs b/essentials-framework/Essentials DM/Essentials_DM/IDmSwitch.cs
index fdbe4956..cf3f963e 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/IDmSwitch.cs
+++ b/essentials-framework/Essentials DM/Essentials_DM/IDmSwitch.cs
@@ -16,10 +16,17 @@ using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM {
- public interface IDmSwitch {
+ public interface IDmSwitch
+ {
Switch Chassis { get; }
Dictionary TxDictionary { get; }
Dictionary RxDictionary { get; }
}
+
+ public interface IDmSwitchWithEndpointOnlineFeedback : IDmSwitch
+ {
+ Dictionary InputEndpointOnlineFeedbacks { get; }
+ Dictionary OutputEndpointOnlineFeedbacks { get; }
+ }
}
\ No newline at end of file
diff --git a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj
index 41b07237..60bdad85 100644
--- a/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj
+++ b/essentials-framework/Essentials DM/Essentials_DM/PepperDash_Essentials_DM.csproj
@@ -59,7 +59,7 @@
..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll
-
+
False
..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll
@@ -104,7 +104,13 @@
+
+
+
+
+
+
@@ -151,6 +157,7 @@
+
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs
index 9169fd7c..c4473c67 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Codec/iHasScheduleAwareness.cs
@@ -216,6 +216,10 @@ namespace PepperDash.Essentials.Devices.Common.Codec
return joinable;
}
}
+
+ [JsonProperty("dialable")]
+ public bool Dialable { get; set; }
+
//public string ConferenceNumberToDial { get; set; }
[JsonProperty("conferencePassword")]
public string ConferencePassword { get; set; }
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
index a1cc37f2..845b61ef 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj
@@ -63,7 +63,7 @@
..\..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Lighting.dll
-
+
False
..\..\..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs
index 59823bb9..05456ad4 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/BookingsDataClasses.cs
@@ -348,6 +348,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (b.DialInfo.ConnectMode.Value.ToLower() == "obtp" || b.DialInfo.ConnectMode.Value.ToLower() == "manual")
meeting.IsOneButtonToPushMeeting = true;
+ meeting.Dialable = b.DialInfo.Calls.Call.Count > 0;
+
if (b.DialInfo.Calls.Call != null)
{
foreach (Call c in b.DialInfo.Calls.Call)
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
index 44d3f423..1a842bc5 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs
@@ -940,7 +940,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
//digitals
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, meeting.Joinable);
- tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Id != "0");
+ tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, meeting.Dialable);
//serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer);
@@ -994,7 +994,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
//Special Change for protected directory clear
- trilist.SetBoolSigAction(joinMap.DirectoryClearSelected.JoinNumber, (b) => SelectDirectoryEntry(_directoryCodec, 0, _directoryTrilist, _directoryJoinmap));
+ trilist.SetBoolSigAction(joinMap.DirectoryClearSelected.JoinNumber, (b) => SelectDirectoryEntry(codec, 0, trilist, joinMap));
// Report feedback for number of contact methods for selected contact
@@ -1004,7 +1004,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
if (codec.DirectoryRoot != null)
{
- trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)codec.DirectoryRoot.CurrentDirectoryResults.Count);
+ var contactsCount = codec.DirectoryRoot.CurrentDirectoryResults.Where(c => c.ParentFolderId.Equals("root")).ToList().Count;
+ trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)contactsCount);
+ Debug.Console(2, this, ">>> contactsCount: {0}", contactsCount);
var clearBytes = XSigHelpers.ClearOutputs();
@@ -1020,7 +1022,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
codec.DirectoryResultReturned += (sender, args) =>
{
- trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)args.Directory.CurrentDirectoryResults.Count);
+ var isRoot = codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false;
+ var argsCount = isRoot
+ ? args.Directory.CurrentDirectoryResults.Where(a => a.ParentFolderId.Equals("root")).ToList().Count
+ : args.Directory.CurrentDirectoryResults.Count;
+
+ trilist.SetUshort(joinMap.DirectoryRowCount.JoinNumber, (ushort)argsCount);
+ Debug.Console(2, this, ">>> argsCount: {0}", argsCount);
var clearBytes = XSigHelpers.ClearOutputs();
@@ -1184,46 +1192,47 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
return GetXSigString(tokenArray);
}
- private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot)
- {
- var xSigMaxIndex = 1023;
- var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count > xSigMaxIndex
- ? xSigMaxIndex
- : directory.CurrentDirectoryResults.Count];
+ private string UpdateDirectoryXSig(CodecDirectory directory, bool isRoot)
+ {
+ var xSigMaxIndex = 1023;
+ var tokenArray = new XSigToken[directory.CurrentDirectoryResults.Count > xSigMaxIndex
+ ? xSigMaxIndex
+ : directory.CurrentDirectoryResults.Count];
- Debug.Console(2, this, "IsRoot: {0}, Directory Count: {1}, TokenArray.Length: {2}", isRoot,
- directory.CurrentDirectoryResults.Count, tokenArray.Length);
+ Debug.Console(2, this, "IsRoot: {0}, Directory Count: {1}, TokenArray.Length: {2}", isRoot, directory.CurrentDirectoryResults.Count, tokenArray.Length);
- var contacts = directory.CurrentDirectoryResults.Count > xSigMaxIndex
- ? directory.CurrentDirectoryResults.Take(xSigMaxIndex)
- : directory.CurrentDirectoryResults;
+ var contacts = directory.CurrentDirectoryResults.Count > xSigMaxIndex
+ ? directory.CurrentDirectoryResults.Take(xSigMaxIndex)
+ : directory.CurrentDirectoryResults;
- var counterIndex = 1;
- foreach (var entry in contacts)
- {
- var arrayIndex = counterIndex - 1;
- var entryIndex = counterIndex;
+ var contactsToDisplay = isRoot
+ ? contacts.Where(c => c.ParentFolderId == "root")
+ : contacts.Where(c => c.ParentFolderId != "root");
- Debug.Console(2, this, "Entry{2:0000} Name: {0}, Folder ID: {1}", entry.Name, entry.FolderId, entryIndex);
+ var counterIndex = 1;
+ foreach (var entry in contactsToDisplay)
+ {
+ var arrayIndex = counterIndex - 1;
+ var entryIndex = counterIndex;
- if (entry is DirectoryFolder && entry.ParentFolderId == "root")
- {
- tokenArray[arrayIndex] = new XSigSerialToken(entryIndex, String.Format("[+] {0}", entry.Name));
+ Debug.Console(2, this, "Entry{2:0000} Name: {0}, Folder ID: {1}, Type: {3}, ParentFolderId: {4}",
+ entry.Name, entry.FolderId, entryIndex, entry.GetType().GetCType().FullName, entry.ParentFolderId);
- counterIndex++;
- counterIndex++;
+ if (entry is DirectoryFolder)
+ {
+ tokenArray[arrayIndex] = new XSigSerialToken(entryIndex, String.Format("[+] {0}", entry.Name));
- continue;
- }
+ counterIndex++;
- tokenArray[arrayIndex] = new XSigSerialToken(entryIndex, entry.Name);
+ continue;
+ }
- counterIndex++;
- }
-
- return GetXSigString(tokenArray);
+ tokenArray[arrayIndex] = new XSigSerialToken(entryIndex, entry.Name);
+ counterIndex++;
+ }
+ return GetXSigString(tokenArray);
}
private void LinkVideoCodecCallControlsToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
@@ -1393,11 +1402,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, call.IsOnHold);
//serials
- tokenArray[arrayIndex] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty);
- tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty);
- tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString());
- tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 4, call.Type.ToString());
- tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 5, call.Status.ToString());
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, call.Name ?? String.Empty);
+ tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, call.Number ?? String.Empty);
+ tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, call.Direction.ToString());
+ tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, call.Type.ToString());
+ tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, call.Status.ToString());
if(call.Duration != null)
{
// May need to verify correct string format here
@@ -1417,12 +1426,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
//serials
- tokenArray[arrayIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
- tokenArray[arrayIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty);
- tokenArray[arrayIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty);
- tokenArray[arrayIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty);
- tokenArray[arrayIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty);
- tokenArray[arrayIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty);
+ tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
+ tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, String.Empty);
+ tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, String.Empty);
+ tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, String.Empty);
+ tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, String.Empty);
+ tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, String.Empty);
arrayIndex += offset;
stringIndex += maxStrings;
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
index 0075b657..09069146 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ResponseObjects.cs
@@ -303,11 +303,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
var contact = new InvitableDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
- contact.ContactMethods.Add(new ContactMethod() { Number = c.Jid, Device = eContactMethodDevice.Video, CallType = eContactMethodCallType.Video, ContactMethodId = c.Jid });
+ contact.ContactMethods.Add(new ContactMethod()
+ {
+ Number = c.Jid,
+ Device = eContactMethodDevice.Video,
+ CallType = eContactMethodCallType.Video,
+ ContactMethodId = c.Jid
+ });
if (folders.Count > 0)
{
- contact.ParentFolderId = c.IsZoomRoom ? "rooms" : "contacts";
+ contact.ParentFolderId = c.IsZoomRoom
+ ? roomFolder.FolderId // "rooms"
+ : contactFolder.FolderId; // "contacts"
}
contacts.Add(contact);
@@ -1502,6 +1510,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
meeting.Privacy = b.IsPrivate ? eMeetingPrivacy.Private : eMeetingPrivacy.Public;
+ meeting.Dialable = meeting.Id != "0";
+
// No meeting.Calls data exists for Zoom Rooms. Leaving out for now.
var now = DateTime.Now;
if (meeting.StartTime < now && meeting.EndTime < now)
diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
index 820d3ab1..1a70b2af 100644
--- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
+++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/ZoomRoom/ZoomRoom.cs
@@ -59,9 +59,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
private CameraBase _selectedCamera;
private string _lastDialedMeetingNumber;
+ private CTimer contactsDebounceTimer;
+
private readonly ZoomRoomPropertiesConfig _props;
+ private bool _meetingPasswordRequired;
+
+ private bool _waitingForUserToAcceptOrRejectIncomingCall;
+
+ public void Poll(string pollString)
+ {
+ if(_meetingPasswordRequired || _waitingForUserToAcceptOrRejectIncomingCall) return;
+
+ SendText(string.Format("{0}{1}", pollString, SendDelimiter));
+ }
+
public ZoomRoom(DeviceConfig config, IBasicCommunication comm)
: base(config)
{
@@ -75,13 +88,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
if (_props.CommunicationMonitorProperties != null)
{
- CommunicationMonitor = new GenericCommunicationMonitor(this, Communication,
- _props.CommunicationMonitorProperties);
+ CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, _props.CommunicationMonitorProperties.PollInterval, _props.CommunicationMonitorProperties.TimeToWarning, _props.CommunicationMonitorProperties.TimeToError,
+ () => Poll(_props.CommunicationMonitorProperties.PollString));
}
else
{
- CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000,
- "zStatus SystemUnit" + SendDelimiter);
+ CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, 30000, 120000, 300000, () => Poll("zStatus SystemUnit"));
}
DeviceManager.AddDevice(CommunicationMonitor);
@@ -366,26 +378,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public void SelectCamera(string key)
{
- if (Cameras == null)
- {
- return;
- }
+ if (CameraIsMutedFeedback.BoolValue)
+ {
+ CameraMuteOff();
+ }
- var camera = Cameras.FirstOrDefault(c => c.Key.IndexOf(key, StringComparison.OrdinalIgnoreCase) > -1);
- if (camera != null)
- {
- Debug.Console(1, this, "Selected Camera with key: '{0}'", camera.Key);
- SelectedCamera = camera;
-
- if (CameraIsMutedFeedback.BoolValue)
- {
- CameraMuteOff();
- }
- }
- else
- {
- Debug.Console(1, this, "Unable to select camera with key: '{0}'", key);
- }
+ SendText(string.Format("zConfiguration Video Camera selectedId: {0}", key));
}
public CameraBase FarEndCamera { get; private set; }
@@ -648,8 +646,27 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
if (a.PropertyName == "SelectedId")
{
- SelectCamera(Configuration.Video.Camera.SelectedId);
- // this will in turn fire the affected feedbacks
+ if (Cameras == null)
+ {
+ return;
+ }
+
+ var camera = Cameras.FirstOrDefault(c => c.Key.IndexOf(Configuration.Video.Camera.SelectedId, StringComparison.OrdinalIgnoreCase) > -1);
+ if (camera != null)
+ {
+ Debug.Console(1, this, "Camera selected with key: '{0}'", camera.Key);
+
+ SelectedCamera = camera;
+
+ if (CameraIsMutedFeedback.BoolValue)
+ {
+ CameraMuteOff();
+ }
+ }
+ else
+ {
+ Debug.Console(1, this, "No camera found with key: '{0}'", Configuration.Video.Camera.SelectedId);
+ }
}
};
@@ -960,6 +977,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public void SendText(string command)
{
+ if (_meetingPasswordRequired)
+ {
+ Debug.Console(2, this, "Blocking commands to ZoomRoom while waiting for user to enter meeting password");
+ return;
+ }
+
+ if (_waitingForUserToAcceptOrRejectIncomingCall)
+ {
+ Debug.Console(2, this, "Blocking commands to ZoomRoom while waiting for user to accept or reject incoming call");
+ return;
+ }
+
if (CommDebuggingIsOn)
{
Debug.Console(1, this, "Sending: '{0}'", command);
@@ -1355,22 +1384,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
JsonConvert.PopulateObject(responseObj.ToString(), Status.Phonebook);
- var directoryResults =
- zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts);
-
- if (!PhonebookSyncState.InitialSyncComplete)
- {
- PhonebookSyncState.InitialPhonebookFoldersReceived();
- PhonebookSyncState.PhonebookRootEntriesReceived();
- PhonebookSyncState.SetPhonebookHasFolders(true);
- PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count);
- }
-
- directoryResults.ResultsFolderId = "root";
-
- DirectoryRoot = directoryResults;
-
- CurrentDirectoryResult = directoryResults;
+ UpdateDirectory();
break;
}
@@ -1499,36 +1513,37 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
case "phonebook":
{
+ zStatus.Contact contact = new zStatus.Contact();
+
if (responseObj["Updated Contact"] != null)
- {
- var updatedContact =
- JsonConvert.DeserializeObject(
- responseObj["Updated Contact"].ToString());
-
- var existingContact =
- Status.Phonebook.Contacts.FirstOrDefault(c => c.Jid.Equals(updatedContact.Jid));
-
- if (existingContact != null)
- {
- // Update existing contact
- JsonConvert.PopulateObject(responseObj["Updated Contact"].ToString(),
- existingContact);
- }
+ {
+ contact = responseObj["Updated Contact"].ToObject();
}
else if (responseObj["Added Contact"] != null)
{
- var jToken = responseObj["Updated Contact"];
- if (jToken != null)
- {
- var newContact =
- JsonConvert.DeserializeObject(
- jToken.ToString());
-
- // Add a new contact
- Status.Phonebook.Contacts.Add(newContact);
- }
+ contact = responseObj["Added Contact"].ToObject();
}
+ var existingContactIndex = Status.Phonebook.Contacts.FindIndex(c => c.Jid.Equals(contact.Jid));
+
+ if (existingContactIndex > 0)
+ {
+ Status.Phonebook.Contacts[existingContactIndex] = contact;
+ }
+ else
+ {
+ Status.Phonebook.Contacts.Add(contact);
+ }
+
+ if(contactsDebounceTimer == null)
+ {
+ contactsDebounceTimer = new CTimer(o => UpdateDirectory(), 2000);
+ }
+ else
+ {
+ contactsDebounceTimer.Reset();
+ }
+
break;
}
case "bookingslistresult":
@@ -1584,6 +1599,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
Id = incomingCall.callerJID
};
+ _waitingForUserToAcceptOrRejectIncomingCall = true;
+
ActiveCalls.Add(newCall);
OnCallStatusChange(newCall);
@@ -1610,6 +1627,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
OnCallStatusChange(existingCall);
}
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
UpdateCallStatus();
}
@@ -1992,6 +2011,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
///
private void GetBookings()
{
+ if (_meetingPasswordRequired || _waitingForUserToAcceptOrRejectIncomingCall) return;
+
SendText("zCommand Bookings List");
}
@@ -2179,6 +2200,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
);
}
+ _meetingPasswordRequired = false;
base.OnCallStatusChange(item);
Debug.Console(1, this, "[OnCallStatusChange] Current Call Status: {0}",
@@ -2218,6 +2240,42 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
}
+ private void UpdateDirectory()
+ {
+ Debug.Console(2, this, "Updating directory");
+ var directoryResults = zStatus.Phonebook.ConvertZoomContactsToGeneric(Status.Phonebook.Contacts);
+
+ if (!PhonebookSyncState.InitialSyncComplete)
+ {
+ PhonebookSyncState.InitialPhonebookFoldersReceived();
+ PhonebookSyncState.PhonebookRootEntriesReceived();
+ PhonebookSyncState.SetPhonebookHasFolders(true);
+ PhonebookSyncState.SetNumberOfContacts(Status.Phonebook.Contacts.Count);
+ }
+
+ directoryResults.ResultsFolderId = "root";
+
+ DirectoryRoot = directoryResults;
+
+ CurrentDirectoryResult = directoryResults;
+
+ //
+ if (contactsDebounceTimer != null)
+ {
+ ClearContactDebounceTimer();
+ }
+ }
+
+ private void ClearContactDebounceTimer()
+ {
+ Debug.Console(2, this, "Clearing Timer");
+ if (!contactsDebounceTimer.Disposed && contactsDebounceTimer != null)
+ {
+ contactsDebounceTimer.Dispose();
+ contactsDebounceTimer = null;
+ }
+ }
+
///
/// Will return true if the host is myself (this zoom room)
///
@@ -2549,7 +2607,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
PasswordRequired += (devices, args) =>
{
- Debug.Console(0, this, "***********************************PaswordRequired. Message: {0} Cancelled: {1} Last Incorrect: {2} Failed: {3}", args.Message, args.LoginAttemptCancelled, args.LastAttemptWasIncorrect, args.LoginAttemptFailed);
+ Debug.Console(2, this, "***********************************PaswordRequired. Message: {0} Cancelled: {1} Last Incorrect: {2} Failed: {3}", args.Message, args.LoginAttemptCancelled, args.LastAttemptWasIncorrect, args.LoginAttemptFailed);
if (args.LoginAttemptCancelled)
{
@@ -2626,6 +2684,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public void AcceptCall()
{
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
var incomingCall =
ActiveCalls.FirstOrDefault(
c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming));
@@ -2635,6 +2695,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public override void AcceptCall(CodecActiveCallItem call)
{
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
SendText(string.Format("zCommand Call Accept callerJID: {0}", call.Id));
call.Status = eCodecCallStatus.Connected;
@@ -2646,6 +2708,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public void RejectCall()
{
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
var incomingCall =
ActiveCalls.FirstOrDefault(
c => c.Status.Equals(eCodecCallStatus.Ringing) && c.Direction.Equals(eCodecCallDirection.Incoming));
@@ -2655,6 +2719,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public override void RejectCall(CodecActiveCallItem call)
{
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
SendText(string.Format("zCommand Call Reject callerJID: {0}", call.Id));
call.Status = eCodecCallStatus.Disconnected;
@@ -2781,16 +2847,25 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public void LeaveMeeting()
{
- SendText("zCommand Call Leave");
+ _meetingPasswordRequired = false;
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
+ SendText("zCommand Call Leave");
}
public override void EndCall(CodecActiveCallItem call)
{
+ _meetingPasswordRequired = false;
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
SendText("zCommand Call Disconnect");
}
public override void EndAllCalls()
{
+ _meetingPasswordRequired = false;
+ _waitingForUserToAcceptOrRejectIncomingCall = false;
+
SendText("zCommand Call Disconnect");
}
@@ -3440,17 +3515,21 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public void SubmitPassword(string password)
{
+ _meetingPasswordRequired = false;
Debug.Console(2, this, "Password Submitted: {0}", password);
Dial(_lastDialedMeetingNumber, password);
- //OnPasswordRequired(false, false, true, "");
}
void OnPasswordRequired(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message)
{
+ _meetingPasswordRequired = !loginFailed || !loginCancelled;
+
var handler = PasswordRequired;
if (handler != null)
- {
- handler(this, new PasswordPromptEventArgs(lastAttemptIncorrect, loginFailed, loginCancelled, message));
+ {
+ Debug.Console(2, this, "Meeting Password Required: {0}", _meetingPasswordRequired);
+
+ handler(this, new PasswordPromptEventArgs(lastAttemptIncorrect, loginFailed, loginCancelled, message));
}
}
diff --git a/packages.config b/packages.config
index 4c411add..eff6d8ce 100644
--- a/packages.config
+++ b/packages.config
@@ -1,3 +1,3 @@
-
-
\ No newline at end of file
+
+