Merge branch 'development' into feature/room-combining

This commit is contained in:
Neil Dorin
2021-09-22 17:23:38 -06:00
45 changed files with 3655 additions and 1827 deletions

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Describes the functionality required to prompt a user to enter a password
/// </summary>
public interface IPasswordPrompt
{
/// <summary>
/// Notifies when a password is required or is entered incorrectly
/// </summary>
event EventHandler<PasswordPromptEventArgs> PasswordRequired;
/// <summary>
/// Submits the password
/// </summary>
/// <param name="password"></param>
void SubmitPassword(string password);
}
public class PasswordPromptEventArgs : EventArgs
{
/// <summary>
/// Indicates if the last submitted password was incorrect
/// </summary>
public bool LastAttemptWasIncorrect { get; private set; }
/// <summary>
/// Indicates that the login attempt has failed
/// </summary>
public bool LoginAttemptFailed { get; private set; }
/// <summary>
/// Indicates that the process was cancelled and the prompt should be dismissed
/// </summary>
public bool LoginAttemptCancelled { get; private set; }
/// <summary>
/// A message to be displayed to the user
/// </summary>
public string Message { get; private set; }
public PasswordPromptEventArgs(bool lastAttemptIncorrect, bool loginFailed, bool loginCancelled, string message)
{
LastAttemptWasIncorrect = lastAttemptIncorrect;
LoginAttemptFailed = loginFailed;
LoginAttemptCancelled = loginCancelled;
Message = message;
}
}
}

View File

@@ -57,7 +57,7 @@ namespace PepperDash.Essentials.Core
public DescriptionAttribute(string description)
{
Debug.Console(2, "Setting Description: {0}", description);
//Debug.Console(2, "Setting Description: {0}", description);
_Description = description;
}
@@ -74,7 +74,7 @@ namespace PepperDash.Essentials.Core
public ConfigSnippetAttribute(string configSnippet)
{
Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
//Debug.Console(2, "Setting Config Snippet {0}", configSnippet);
_ConfigSnippet = configSnippet;
}
@@ -103,7 +103,7 @@ namespace PepperDash.Essentials.Core
{
foreach (var typeName in TypeNames)
{
Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
//Debug.Console(2, "Getting Description Attribute from class: '{0}'", typeof(T).FullName);
var descriptionAttribute = typeof(T).GetCustomAttributes(typeof(DescriptionAttribute), true) as DescriptionAttribute[];
string description = descriptionAttribute[0].Description;
var snippetAttribute = typeof(T).GetCustomAttributes(typeof(ConfigSnippetAttribute), true) as ConfigSnippetAttribute[];

View File

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

View File

@@ -1,5 +1,6 @@
using System;
using System.Text.RegularExpressions;
using System.Globalization;
using Crestron.SimplSharp;
using System.Collections.Generic;
using Crestron.SimplSharp.CrestronIO;
@@ -28,6 +29,10 @@ namespace PepperDash.Essentials.Core
public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } }
// TODO: consider making this configurable later
public static IFormatProvider Culture = CultureInfo.CreateSpecificCulture("en-US");
/// <summary>
/// The file path prefix to the folder containing configuration files
/// </summary>

View File

@@ -135,6 +135,7 @@ namespace PepperDash.Essentials.Core
public void SetEnableState(bool state)
{
Debug.Console(2, this, "Sensor is {0}, SetEnableState: {1}", _partitionSensor == null ? "null" : "not null", state);
if (_partitionSensor == null)
return;
@@ -143,6 +144,7 @@ namespace PepperDash.Essentials.Core
public void IncreaseSensitivity()
{
Debug.Console(2, this, "Sensor is {0}, IncreaseSensitivity", _partitionSensor == null ? "null" : "not null");
if (_partitionSensor == null)
return;
@@ -151,6 +153,7 @@ namespace PepperDash.Essentials.Core
public void DecreaseSensitivity()
{
Debug.Console(2, this, "Sensor is {0}, DecreaseSensitivity", _partitionSensor == null ? "null" : "not null");
if (_partitionSensor == null)
return;
@@ -159,6 +162,7 @@ namespace PepperDash.Essentials.Core
public void SetSensitivity(ushort value)
{
Debug.Console(2, this, "Sensor is {0}, SetSensitivity: {1}", _partitionSensor == null ? "null" : "not null", value);
if (_partitionSensor == null)
return;
@@ -186,8 +190,7 @@ namespace PepperDash.Essentials.Core
Debug.Console(0, this, "Linking to Bridge Type {0}", GetType().Name);
// link input from simpl
trilist.SetSigTrueAction(joinMap.Enable.JoinNumber, () => SetEnableState(true));
trilist.SetSigFalseAction(joinMap.Enable.JoinNumber, () => SetEnableState(false));
trilist.SetBoolSigAction(joinMap.Enable.JoinNumber, SetEnableState);
trilist.SetSigTrueAction(joinMap.IncreaseSensitivity.JoinNumber, IncreaseSensitivity);
trilist.SetSigTrueAction(joinMap.DecreaseSensitivity.JoinNumber, DecreaseSensitivity);
trilist.SetUShortSigAction(joinMap.Sensitivity.JoinNumber, SetSensitivity);

View File

@@ -203,6 +203,7 @@
<Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" />
<Compile Include="DeviceTypeInterfaces\ITvPresetsProvider.cs" />
<Compile Include="DeviceTypeInterfaces\LanguageLabel.cs" />
<Compile Include="DeviceTypeInterfaces\ILanguageProvider.cs" />

View File

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

View File

@@ -123,7 +123,7 @@ namespace PepperDash.Essentials
/// <param name="fileName"></param>
static LoadedAssembly LoadAssembly(string filePath)
{
Debug.Console(2, "Attempting to load {0}", filePath);
//Debug.Console(2, "Attempting to load {0}", filePath);
var assembly = Assembly.LoadFrom(filePath);
if (assembly != null)
{

View File

@@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Core
/// <summary>
/// Describes the basic functionality of an EssentialsRoom
/// </summary>
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice
public interface IEssentialsRoom : IKeyName, IReconfigurableDevice, IRunDefaultPresentRoute
{
BoolFeedback OnFeedback { get; }
@@ -56,7 +56,6 @@ namespace PepperDash.Essentials.Core
void SetRoomOccupancy(IOccupancyStatusProvider statusProvider, int timeoutMinutes);
void PowerOnToDefaultOrLastSource();
bool RunDefaultPresentRoute();
void SetDefaultLevels();

View File

@@ -8,6 +8,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Cards;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpProInternal;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
@@ -482,6 +483,24 @@ namespace PepperDash.Essentials.DM
}
private void RegisterForInputResolutionFeedback(IVideoAttributesBasic input, uint number, RoutingInputPortWithVideoStatuses inputPort)
{
if (input == null)
{
return;
}
Debug.Console(1, this, "Registering for resolution feedback for input {0} using Routing Port {1}", number, inputPort.Key);
input.VideoAttributes.AttributeChange += (sender, args) =>
{
Debug.Console(1, this, "Input {0} resolution updated", number);
Debug.Console(1, this, "Updating resolution feedback for input {0}", number);
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
};
}
/// <summary>
///
/// </summary>
@@ -497,166 +516,189 @@ namespace PepperDash.Essentials.DM
{
case "dmchd":
{
var inputCard = new DmcHd(number, this.Chassis);
var cecPort = inputCard.HdmiInput as ICec;
AddHdmiInCardPorts(number, cecPort);
var inputCard = new DmcHd(number, Chassis);
AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput);
}
break;
case "dmchddsp":
{
var inputCard = new DmcHdDsp(number, this.Chassis);
var cecPort = inputCard.HdmiInput as ICec;
AddHdmiInCardPorts(number, cecPort);
var inputCard = new DmcHdDsp(number, Chassis);
AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput);
}
break;
case "dmc4khd":
{
var inputCard = new Dmc4kHd(number, this.Chassis);
var cecPort = inputCard.HdmiInput as ICec;
AddHdmiInCardPorts(number, cecPort);
var inputCard = new Dmc4kHd(number, Chassis);
AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput);
}
break;
case "dmc4khddsp":
{
var inputCard = new Dmc4kHdDsp(number, this.Chassis);
var cecPort = inputCard.HdmiInput as ICec;
AddHdmiInCardPorts(number, cecPort);
var inputCard = new Dmc4kHdDsp(number, Chassis);
AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput);
}
break;
case "dmc4kzhd":
{
var inputCard = new Dmc4kzHd(number, this.Chassis);
var cecPort = inputCard.HdmiInput as ICec;
AddHdmiInCardPorts(number, cecPort);
}
var inputCard = new Dmc4kzHd(number, Chassis);
AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput);
break;
}
case "dmc4kzhddsp":
{
var inputCard = new Dmc4kzHdDsp(number, this.Chassis);
var cecPort = inputCard.HdmiInput as ICec;
AddHdmiInCardPorts(number, cecPort);
}
var inputCard = new Dmc4kzHdDsp(number, Chassis);
AddHdmiInCardPorts(number, inputCard.HdmiInput, inputCard.HdmiInput);
break;
}
case "dmcc":
{
var inputCard = new DmcC(number, this.Chassis);
var cecPort = inputCard.DmInput as ICec;
AddDmInCardPorts(number, cecPort);
var inputCard = new DmcC(number, Chassis);
//DmInput doesn't implement ICec...cast was resulting in null anyway
AddDmInCardPorts(number, null, inputCard.DmInput);
}
break;
case "dmccdsp":
{
var inputCard = new DmcCDsp(number, this.Chassis);
var cecPort = inputCard.DmInput as ICec;
AddDmInCardPorts(number, cecPort);
}
var inputCard = new DmcCDsp(number, Chassis);
//DmInput doesn't implement ICec...cast was resulting in null anyway
AddDmInCardPorts(number, null, inputCard.DmInput);
break;
}
case "dmc4kc":
{
var inputCard = new Dmc4kC(number, this.Chassis);
var cecPort = inputCard.DmInput as ICec;
AddDmInCardPorts(number, cecPort);
}
var inputCard = new Dmc4kC(number, Chassis);
AddDmInCardPorts(number, inputCard.DmInput,inputCard.DmInput);
break;
}
case "dmc4kcdsp":
{
var inputCard = new Dmc4kCDsp(number, this.Chassis);
var cecPort = inputCard.DmInput as ICec;
AddDmInCardPorts(number, cecPort);
}
var inputCard = new Dmc4kCDsp(number, Chassis);
AddDmInCardPorts(number, inputCard.DmInput,inputCard.DmInput);
break;
}
case "dmc4kzc":
{
var inputCard = new Dmc4kzC(number, this.Chassis);
var cecPort = inputCard.DmInput as ICec;
AddDmInCardPorts(number, cecPort);
}
var inputCard = new Dmc4kzC(number, Chassis);
AddDmInCardPorts(number, inputCard.DmInput,inputCard.DmInput);
break;
}
case "dmc4kzcdsp":
{
var inputCard = new Dmc4kzCDsp(number, this.Chassis);
var cecPort = inputCard.DmInput as ICec;
AddDmInCardPorts(number, cecPort);
var inputCard = new Dmc4kzCDsp(number, Chassis);
AddDmInCardPorts(number, inputCard.DmInput, inputCard.DmInput);
break;
}
break;
case "dmccat":
new DmcCat(number, this.Chassis);
AddDmInCardPorts(number);
{
var inputCard = new DmcCat(number, Chassis);
AddDmInCardPorts(number, null, inputCard.DmInput);
break;
}
case "dmccatdsp":
new DmcCatDsp(number, this.Chassis);
AddDmInCardPorts(number);
{
var inputCard = new DmcCatDsp(number, Chassis);
AddDmInCardPorts(number, null, inputCard.DmInput);
break;
}
case "dmcs":
new DmcS(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
{
var inputCard = new DmcS(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, null, inputCard.DmInput);
AddInCardHdmiAndAudioLoopPorts(number);
break;
}
case "dmcsdsp":
new DmcSDsp(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber);
{
var inputCard = new DmcSDsp(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmMmFiber, null, inputCard.DmInput);
AddInCardHdmiAndAudioLoopPorts(number);
break;
}
case "dmcs2":
new DmcS2(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
{
var inputCard = new DmcS2(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, null, inputCard.DmInput);
AddInCardHdmiAndAudioLoopPorts(number);
break;
}
case "dmcs2dsp":
new DmcS2Dsp(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber);
{
var inputCard = new DmcS2Dsp(number, Chassis);
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmSmFiber, null, inputCard.DmInput);
AddInCardHdmiAndAudioLoopPorts(number);
break;
}
case "dmcsdi":
new DmcSdi(number, Chassis);
AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi);
{
var inputCard = new DmcSdi(number, Chassis);
AddInputPortWithDebug(number, "sdiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Sdi, null, inputCard.SdiInput);
AddOutputPortWithDebug(string.Format("inputCard{0}", number), "sdiOut", eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Sdi, null);
AddInCardHdmiAndAudioLoopPorts(number);
break;
}
case "dmcdvi":
new DmcDvi(number, Chassis);
AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi);
{
var inputCard = new DmcDvi(number, Chassis);
AddInputPortWithDebug(number, "dviIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Dvi, null, inputCard.DviInput);
AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio);
AddInCardHdmiLoopPort(number);
break;
}
case "dmcvga":
new DmcVga(number, Chassis);
AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga);
{
var inputCard = new DmcVga(number, Chassis);
AddInputPortWithDebug(number, "vgaIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Vga, null, inputCard.VgaInput);
AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio);
AddInCardHdmiLoopPort(number);
break;
}
case "dmcvidbnc":
new DmcVidBnc(number, Chassis);
AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component);
{
var inputCard = new DmcVidBnc(number, Chassis);
AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component, null, inputCard.VideoInput);
AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio);
AddInCardHdmiLoopPort(number);
break;
}
case "dmcvidrcaa":
new DmcVidRcaA(number, Chassis);
AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component);
{
var inputCard = new DmcVidRcaA(number, Chassis);
AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component, null, inputCard.VideoInput);
AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.LineAudio);
AddInCardHdmiLoopPort(number);
break;
}
case "dmcvidrcad":
new DmcVidRcaD(number, Chassis);
AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component);
{
var inputCard = new DmcVidRcaD(number, Chassis);
AddInputPortWithDebug(number, "componentIn", eRoutingSignalType.Video, eRoutingPortConnectionType.Component, null, inputCard.VideoInput);
AddInputPortWithDebug(number, "audioIn", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio);
AddInCardHdmiLoopPort(number);
break;
}
case "dmcvid4":
new DmcVid4(number, Chassis);
{
var inputCard = new DmcVid4(number, Chassis);
AddInputPortWithDebug(number, "compositeIn1", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite);
AddInputPortWithDebug(number, "compositeIn2", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite);
AddInputPortWithDebug(number, "compositeIn3", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite);
AddInputPortWithDebug(number, "compositeIn4", eRoutingSignalType.Video, eRoutingPortConnectionType.Composite);
AddInCardHdmiLoopPort(number);
break;
}
case "dmcstr":
new DmcStr(number, Chassis);
AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming);
{
var inputCard = new DmcStr(number, Chassis);
AddInputPortWithDebug(number, "streamIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming, null, inputCard.Source);
AddInCardHdmiAndAudioLoopPorts(number);
break;
}
}
}
@@ -672,12 +714,24 @@ namespace PepperDash.Essentials.DM
AddInCardHdmiAndAudioLoopPorts(number);
}
void AddDmInCardPorts(uint number, ICec cecPort, IVideoAttributesBasic videoAttributes)
{
AddInputPortWithDebug(number, "dmIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort, videoAttributes);
AddInCardHdmiAndAudioLoopPorts(number);
}
void AddHdmiInCardPorts(uint number, ICec cecPort)
{
AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort);
AddInCardHdmiAndAudioLoopPorts(number);
}
void AddHdmiInCardPorts(uint number, ICec cecPort, IVideoAttributesBasic videoAttributes)
{
AddInputPortWithDebug(number, "hdmiIn", eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort, videoAttributes);
AddInCardHdmiAndAudioLoopPorts(number);
}
void AddInCardHdmiAndAudioLoopPorts(uint number)
{
AddOutputPortWithDebug(string.Format("inputCard{0}", number), "hdmiLoopOut", eRoutingSignalType.Audio | eRoutingSignalType.Video,
@@ -816,20 +870,55 @@ namespace PepperDash.Essentials.DM
/// </summary>
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType)
{
AddInputPortWithDebug(cardNum, portName, sigType, portType, null);
//Cast is necessary here to determine the correct overload
AddInputPortWithDebug(cardNum, portName, sigType, portType, null, null);
}
private void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType,
eRoutingPortConnectionType portType, ICec cecPort)
{
//Cast is necessary here to determine the correct overload
AddInputPortWithDebug(cardNum, portName, sigType, portType, cecPort, null);
}
/// <summary>
/// Adds InputPort and sets Port as ICec object
/// Adds InputPort and sets Port as ICec object. If videoAttributesBasic is defined, RoutingPort will be RoutingInputPortWithVideoStatuses
/// </summary>
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort)
void AddInputPortWithDebug(uint cardNum, string portName, eRoutingSignalType sigType, eRoutingPortConnectionType portType, ICec cecPort, IVideoAttributesBasic videoAttributesBasic)
{
var portKey = string.Format("inputCard{0}--{1}", cardNum, portName);
Debug.Console(2, this, "Adding input port '{0}'", portKey);
var inputPort = new RoutingInputPort(portKey, sigType, portType, Chassis.Inputs[cardNum], this)
RoutingInputPort inputPort;
if (videoAttributesBasic != null)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
}; ;
Debug.Console(1, this, "card {0} supports IVideoAttributesBasic", cardNum);
var statusFuncs = new VideoStatusFuncsWrapper
{
VideoResolutionFeedbackFunc = () =>
{
var resolution = videoAttributesBasic.VideoAttributes.GetVideoResolutionString();
Debug.Console(1, this, "Updating resolution for input {0}. New resolution: {1}", cardNum, resolution);
return resolution;
}
};
inputPort = new RoutingInputPortWithVideoStatuses(portKey, sigType, portType,
Chassis.Inputs[cardNum], this, statusFuncs)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
};
RegisterForInputResolutionFeedback(videoAttributesBasic, cardNum, inputPort as RoutingInputPortWithVideoStatuses);
}
else
{
inputPort = new RoutingInputPort(portKey, sigType, portType,
Chassis.Inputs[cardNum], this)
{
FeedbackMatchObject = Chassis.Inputs[cardNum]
};
}
if (cecPort != null)
inputPort.Port = cecPort;
@@ -989,6 +1078,23 @@ namespace PepperDash.Essentials.DM
Debug.Console(2, this, "No index of {0} found in InputStreamCardStateFeedbacks");
break;
}
case DMInputEventIds.HorizontalResolutionFeedbackEventId:
case DMInputEventIds.VerticalResolutionFeedbackEventId:
case DMInputEventIds.FramesPerSecondFeedbackEventId:
case DMInputEventIds.ResolutionEventId:
{
Debug.Console(1, this, "Input {0} resolution updated", args.Number);
var inputPort =
InputPorts.Cast<RoutingInputPortWithVideoStatuses>()
.FirstOrDefault((ip) => ip.Key.Contains(String.Format("inputCard{0}", args.Number)));
if (inputPort != null)
{
Debug.Console(1, this, "Updating resolution feedback for input {0}", args.Number);
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
}
break;
}
default:
{
Debug.Console(2, this, "DMInputChange fired for Input {0} with Unhandled EventId: {1}", args.Number, args.EventId);
@@ -1050,7 +1156,7 @@ namespace PepperDash.Essentials.DM
var inputNumber = Chassis.Outputs[output].VideoOutFeedback == null ? 0 : Chassis.
Outputs[output].VideoOutFeedback.Number;
Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output);
Debug.Console(2, this, "DMSwitchVideo:{0} Routed Input:{1} Output:{2}'", Name, inputNumber, output);
if (VideoOutputFeedbacks.ContainsKey(output))
{
@@ -1077,7 +1183,7 @@ namespace PepperDash.Essentials.DM
var inputNumber = Chassis.Outputs[output].AudioOutFeedback == null ? 0 : Chassis.
Outputs[output].AudioOutFeedback.Number;
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, inputNumber, output);
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name, inputNumber, output);
if (AudioOutputFeedbacks.ContainsKey(output))
{
@@ -1388,6 +1494,16 @@ namespace PepperDash.Essentials.DM
{
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1;
}
var videoStatus = inputPort as RoutingInputPortWithVideoStatuses;
if (videoStatus == null)
{
return;
}
Debug.Console(1, this, "Linking {0} to join {1} for resolution feedback.", videoStatus.Key, joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin);
videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]);
}
private void LinkStreamInputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin)
@@ -1428,6 +1544,13 @@ namespace PepperDash.Essentials.DM
InputStreamCardStateFeedbacks[ioSlot].LinkInputSig(trilist.UShortInput[join]);
trilist.UShortInput[join].UShortValue = InputStreamCardStateFeedbacks[ioSlot].UShortValue;
var videoStatus = inputPort as RoutingInputPortWithVideoStatuses;
if (videoStatus != null)
{
videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]);
}
}
private void LinkStreamOutputToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap, uint ioSlotJoin)
@@ -1564,10 +1687,19 @@ namespace PepperDash.Essentials.DM
{
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue = 1;
}
var videoStatus = inputPort as RoutingInputPortWithVideoStatuses;
if (videoStatus == null)
{
return;
}
Debug.Console(1, this, "Linking {0} to join {1} for resolution feedback.", videoStatus.Key, joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin);
videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]);
}
private void LinkAdvancedTxToApi(BasicTriList trilist, DmChassisControllerJoinMap joinMap,
uint ioSlot, uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter)
uint ioSlot, uint ioSlotJoin, BasicDmTxControllerBase basicTransmitter)
{
var transmitter = basicTransmitter as DmTxControllerBase;
if (transmitter == null) return;
@@ -1581,7 +1713,9 @@ namespace PepperDash.Essentials.DM
if (txRoutingInputs == null) return;
var inputPorts = txRoutingInputs.InputPorts.Where((p) => p.Port is EndpointHdmiInput || p.Port is EndpointDisplayPortInput).ToList();
var inputPorts =
txRoutingInputs.InputPorts.Where(
(p) => p.Port is EndpointHdmiInput || p.Port is EndpointDisplayPortInput).ToList();
if (inputPorts.Count == 0)
{
@@ -1614,6 +1748,19 @@ namespace PepperDash.Essentials.DM
trilist.UShortInput[joinMap.HdcpSupportCapability.JoinNumber + ioSlotJoin].UShortValue =
(ushort) transmitter.HdcpSupportCapability;
var videoStatus =
InputPorts[string.Format("inputCard{0}--dmIn", ioSlot)] as RoutingInputPortWithVideoStatuses;
if (videoStatus == null)
{
return;
}
Debug.Console(1, this, "Linking {0} to join {1} for resolution feedback.", videoStatus.Key,
joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin);
videoStatus.VideoStatus.VideoResolutionFeedback.LinkInputSig(
trilist.StringInput[joinMap.InputCurrentResolution.JoinNumber + ioSlotJoin]);
}
private void LinkTxOnlineFeedbackToApi(BasicTriList trilist, uint ioSlot, DmChassisControllerJoinMap joinMap,
@@ -1896,15 +2043,15 @@ namespace PepperDash.Essentials.DM
{
var props = JsonConvert.DeserializeObject
<PepperDash.Essentials.DM.Config.DMChassisPropertiesConfig>(dc.Properties.ToString());
return PepperDash.Essentials.DM.DmChassisController.
<DMChassisPropertiesConfig>(dc.Properties.ToString());
return DmChassisController.
GetDmChassisController(dc.Key, dc.Name, type, props);
}
else if (type.StartsWith("dmmd128x") || type.StartsWith("dmmd64x"))
{
var props = JsonConvert.DeserializeObject
<PepperDash.Essentials.DM.Config.DMChassisPropertiesConfig>(dc.Properties.ToString());
return PepperDash.Essentials.DM.DmBladeChassisController.
<DMChassisPropertiesConfig>(dc.Properties.ToString());
return DmBladeChassisController.
GetDmChassisController(dc.Key, dc.Name, type, props);
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
@@ -15,421 +16,489 @@ using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM.Chassis
{
[Description("Wrapper class for all HdMdNxM4E switchers")]
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
{
private HdMdNxM _Chassis;
private HdMd4x14kE _Chassis4x1;
[Description("Wrapper class for all HdMdNxM4E switchers")]
public class HdMdNxM4kEBridgeableController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
{
private HdMdNxM _Chassis;
private HdMd4x14kE _Chassis4x1;
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
public Dictionary<uint, string> InputNames { get; set; }
public Dictionary<uint, string> OutputNames { get; set; }
public Dictionary<uint, string> InputNames { get; set; }
public Dictionary<uint, string> OutputNames { get; set; }
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
public RoutingPortCollection<RoutingOutputPort> OutputPorts { get; private set; }
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputRouteNameFeedbacks { get; private set; }
public FeedbackCollection<BoolFeedback> InputHdcpEnableFeedback { get; private set; }
public FeedbackCollection<StringFeedback> DeviceNameFeedback { get; private set; }
public FeedbackCollection<BoolFeedback> AutoRouteFeedback { get; private set; }
public FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputRouteNameFeedbacks { get; private set; }
public FeedbackCollection<BoolFeedback> InputHdcpEnableFeedback { get; private set; }
public StringFeedback DeviceNameFeedback { get; private set; }
public BoolFeedback AutoRouteFeedback { get; private set; }
#region Constructor
#region Constructor
public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis,
HdMdNxM4kEBridgeablePropertiesConfig props)
: base(key, name, chassis)
{
_Chassis = chassis;
var _props = props;
public HdMdNxM4kEBridgeableController(string key, string name, HdMdNxM chassis,
HdMdNxM4kEBridgeablePropertiesConfig props)
: base(key, name, chassis)
{
_Chassis = chassis;
Name = name;
InputNames = props.Inputs;
OutputNames = props.Outputs;
if (props == null)
{
Debug.Console(1, this, "HdMdNx4keBridgeableController properties are null, failed to build the device");
return;
}
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
InputHdcpEnableFeedback = new FeedbackCollection<BoolFeedback>();
DeviceNameFeedback = new FeedbackCollection<StringFeedback>();
AutoRouteFeedback = new FeedbackCollection<BoolFeedback>();
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
if (props.Inputs != null)
{
foreach (var kvp in props.Inputs)
{
Debug.Console(1, this, "props.Inputs: {0}-{1}", kvp.Key, kvp.Value);
}
InputNames = props.Inputs;
}
if (props.Outputs != null)
{
foreach (var kvp in props.Outputs)
{
Debug.Console(1, this, "props.Outputs: {0}-{1}", kvp.Key, kvp.Value);
}
OutputNames = props.Outputs;
}
DeviceNameFeedback.Add(new StringFeedback(this.Name, () => this.Name));
DeviceNameFeedback = new StringFeedback(()=>Name);
if (_Chassis.NumberOfInputs == 1)
{
_Chassis4x1 = _Chassis as HdMd4x14kE;
AutoRouteFeedback.Add(new BoolFeedback(this.Name + "-" + InputNames[1], () => _Chassis4x1.AutoModeOnFeedback.BoolValue));
}
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
InputHdcpEnableFeedback = new FeedbackCollection<BoolFeedback>();
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
var index = i;
var inputName = InputNames[index];
_Chassis.Inputs[index].Name.StringValue = inputName;
if (_Chassis.NumberOfInputs == 1)
{
_Chassis4x1 = _Chassis as HdMd4x14kE;
AutoRouteFeedback = new BoolFeedback(() => _Chassis4x1.AutoModeOnFeedback.BoolValue);
}
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, index, this)
{
FeedbackMatchObject = _Chassis.HdmiInputs[index]
});
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].Name.StringValue));
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
}
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
var index = i;
var inputName = InputNames[index];
//_Chassis.Inputs[index].Name.StringValue = inputName;
_Chassis.HdmiInputs[index].Name.StringValue = inputName;
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
var index = i;
var outputName = OutputNames[index];
_Chassis.Outputs[i].Name.StringValue = outputName;
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, _Chassis.HdmiInputs[index], this)
{
FeedbackMatchObject = _Chassis.HdmiInputs[index]
});
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
//InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].NameFeedback.StringValue));
InputNameFeedbacks.Add(new StringFeedback(inputName, () => InputNames[index]));
InputHdcpEnableFeedback.Add(new BoolFeedback(inputName, () => _Chassis.HdmiInputs[index].HdmiInputPort.HdcpSupportOnFeedback.BoolValue));
}
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, index, this)
{
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
});
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].Name.StringValue));
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
}
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
var index = i;
var outputName = OutputNames[index];
//_Chassis.Outputs[index].Name.StringValue = outputName;
//_Chassis.HdmiOutputs[index].Name.StringValue = outputName;
_Chassis.DMInputChange += new DMInputEventHandler(Chassis_DMInputChange);
_Chassis.DMOutputChange += new DMOutputEventHandler(Chassis_DMOutputChange);
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, _Chassis.HdmiOutputs[index], this)
{
FeedbackMatchObject = _Chassis.HdmiOutputs[index]
});
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => OutputNames[index]));
OutputRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
}
AddPostActivationAction(AddFeedbackCollections);
}
_Chassis.DMInputChange += Chassis_DMInputChange;
_Chassis.DMOutputChange += Chassis_DMOutputChange;
#endregion
AddPostActivationAction(AddFeedbackCollections);
}
#region Methods
#endregion
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
#region Methods
public void EnableHdcp(uint port)
{
if (port > _Chassis.NumberOfInputs) return;
if (port <= 0) return;
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn();
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
}
public void EnableHdcp(uint port)
{
if (port > _Chassis.NumberOfInputs) return;
if (port <= 0) return;
public void DisableHdcp(uint port)
{
if (port > _Chassis.NumberOfInputs) return;
if (port <= 0) return;
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOn();
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
}
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff();
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
}
public void DisableHdcp(uint port)
{
if (port > _Chassis.NumberOfInputs) return;
if (port <= 0) return;
public void EnableAutoRoute()
{
if (_Chassis.NumberOfInputs != 1) return;
_Chassis.HdmiInputs[port].HdmiInputPort.HdcpSupportOff();
InputHdcpEnableFeedback[InputNames[port]].FireUpdate();
}
if (_Chassis4x1 == null) return;
public void EnableAutoRoute()
{
if (_Chassis.NumberOfInputs != 1) return;
_Chassis4x1.AutoModeOn();
}
if (_Chassis4x1 == null) return;
public void DisableAutoRoute()
{
if (_Chassis.NumberOfInputs != 1) return;
_Chassis4x1.AutoModeOn();
}
if (_Chassis4x1 == null) return;
public void DisableAutoRoute()
{
if (_Chassis.NumberOfInputs != 1) return;
_Chassis4x1.AutoModeOff();
}
if (_Chassis4x1 == null) return;
#region PostActivate
_Chassis4x1.AutoModeOff();
}
public void AddFeedbackCollections()
{
AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback);
AddCollectionsToList(VideoOutputRouteFeedbacks);
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks, DeviceNameFeedback);
}
#region PostActivate
#endregion
public void AddFeedbackCollections()
{
AddFeedbackToList(DeviceNameFeedback);
AddCollectionsToList(VideoInputSyncFeedbacks, InputHdcpEnableFeedback);
AddCollectionsToList(VideoOutputRouteFeedbacks);
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputRouteNameFeedbacks);
}
#region FeedbackCollection Methods
#endregion
//Add arrays of collections
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
{
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
{
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
#region FeedbackCollection Methods
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
{
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
//Add arrays of collections
public void AddCollectionsToList(params FeedbackCollection<BoolFeedback>[] newFbs)
{
foreach (FeedbackCollection<BoolFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
public void AddCollectionsToList(params FeedbackCollection<IntFeedback>[] newFbs)
{
foreach (FeedbackCollection<IntFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
//Add Collections
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
{
foreach (FeedbackCollection<StringFeedback> fbCollection in newFbs)
{
foreach (var item in newFbs)
{
AddCollectionToList(item);
}
}
}
AddFeedbackToList(f);
}
}
//Add Collections
public void AddCollectionToList(FeedbackCollection<BoolFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
AddFeedbackToList(f);
}
}
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
AddFeedbackToList(f);
}
}
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
//Add Individual Feedbacks
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
{
if (newFb == null) return;
AddFeedbackToList(f);
}
}
if (!Feedbacks.Contains(newFb))
{
Feedbacks.Add(newFb);
}
}
//Add Individual Feedbacks
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
{
if (newFb == null) return;
#endregion
if (!Feedbacks.Contains(newFb))
{
Feedbacks.Add(newFb);
}
}
#region IRouting Members
#endregion
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
// Try to make switch only when necessary. The unit appears to toggle when already selected.
var current = _Chassis.HdmiOutputs[(uint)outputSelector].VideoOut;
if (current != _Chassis.HdmiInputs[(uint)inputSelector])
_Chassis.HdmiOutputs[(uint)outputSelector].VideoOut = _Chassis.HdmiInputs[(uint)inputSelector];
}
#region IRouting Members
#endregion
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
var input = inputSelector as HdMdNxMHdmiInput; //changed from HdMdNxM4kzEHdmiInput;
var output = outputSelector as HdMdNxMHdmiOutput;
Debug.Console(2, this, "ExecuteSwitch: input={0} output={1}", input, output);
#region IRoutingNumeric Members
if (output == null)
{
Debug.Console(0, this, "Unable to make switch. output selector is not HdMdNxMHdmiOutput");
return;
}
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
{
ExecuteSwitch(inputSelector, outputSelector, signalType);
}
// Try to make switch only when necessary. The unit appears to toggle when already selected.
var current = output.VideoOut;
if (current != input)
output.VideoOut = input;
}
#endregion
#endregion
#endregion
#region IRoutingNumeric Members
#region Bridge Linking
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
{
var input = inputSelector == 0 ? null : _Chassis.HdmiInputs[inputSelector];
var output = _Chassis.HdmiOutputs[outputSelector];
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart);
Debug.Console(2, this, "ExecuteNumericSwitch: input={0} output={1}", input, output);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
ExecuteSwitch(input, output, signalType);
}
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(joinMapSerialized);
#endregion
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.");
}
#endregion
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
DeviceNameFeedback[this.Name].LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new HdMdNxM4kEControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<HdMdNxM4kEControllerJoinMap>(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.");
}
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
DeviceNameFeedback.LinkInputSig(trilist.StringInput[joinMap.Name.JoinNumber]);
if (_Chassis4x1 != null)
{
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
AutoRouteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
}
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
var joinIndex = i - 1;
var input = i;
//Digital
VideoInputSyncFeedbacks[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]);
InputHdcpEnableFeedback[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]);
InputHdcpEnableFeedback[InputNames[input]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]);
trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(input));
trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(input));
//Serial
InputNameFeedbacks[InputNames[input]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]);
}
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
var joinIndex = i - 1;
var output = i;
//Analog
VideoOutputRouteFeedbacks[OutputNames[output]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]);
trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort) output, eRoutingSignalType.AudioVideo));
//Serial
OutputNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]);
OutputRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]);
}
_Chassis.OnlineStatusChange += Chassis_OnlineStatusChange;
trilist.OnlineStatusChange += (d, args) =>
{
if (!args.DeviceOnLine) return;
// feedback updates was moved to the Chassis_OnlineStatusChange
// due to the amount of time it takes for the device to come online
};
}
#endregion
#region Events
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
{
IsOnline.FireUpdate();
if (!args.DeviceOnLine) return;
foreach (var feedback in Feedbacks)
{
feedback.FireUpdate();
}
if (_Chassis4x1 != null)
{
trilist.SetSigTrueAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOn());
trilist.SetSigFalseAction(joinMap.EnableAutoRoute.JoinNumber, () => _Chassis4x1.AutoModeOff());
AutoRouteFeedback[this.Name + "-" + InputNames[1]].LinkInputSig(trilist.BooleanInput[joinMap.EnableAutoRoute.JoinNumber]);
}
AutoRouteFeedback.FireUpdate();
}
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
var joinIndex = i - 1;
//Digital
VideoInputSyncFeedbacks[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.InputSync.JoinNumber + joinIndex]);
InputHdcpEnableFeedback[InputNames[i]].LinkInputSig(trilist.BooleanInput[joinMap.EnableInputHdcp.JoinNumber + joinIndex]);
InputHdcpEnableFeedback[InputNames[i]].LinkComplementInputSig(trilist.BooleanInput[joinMap.DisableInputHdcp.JoinNumber + joinIndex]);
trilist.SetSigTrueAction(joinMap.EnableInputHdcp.JoinNumber + joinIndex, () => EnableHdcp(i));
trilist.SetSigTrueAction(joinMap.DisableInputHdcp.JoinNumber + joinIndex, () => DisableHdcp(i));
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
{
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
//Serial
InputNameFeedbacks[InputNames[i]].LinkInputSig(trilist.StringInput[joinMap.InputName.JoinNumber + joinIndex]);
}
var output = args.Number;
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
var joinIndex = i - 1;
//Analog
VideoOutputRouteFeedbacks[OutputNames[i]].LinkInputSig(trilist.UShortInput[joinMap.OutputRoute.JoinNumber + joinIndex]);
trilist.SetUShortSigAction(joinMap.OutputRoute.JoinNumber + joinIndex, (a) => ExecuteSwitch(a, i, eRoutingSignalType.AudioVideo));
var inputNumber = _Chassis.HdmiOutputs[output].VideoOutFeedback == null
? 0
: _Chassis.HdmiOutputs[output].VideoOutFeedback.Number;
//Serial
OutputNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputName.JoinNumber + joinIndex]);
OutputRouteNameFeedbacks[OutputNames[i]].LinkInputSig(trilist.StringInput[joinMap.OutputRoutedName.JoinNumber + joinIndex]);
}
var outputName = OutputNames[output];
_Chassis.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler(Chassis_OnlineStatusChange);
var feedback = VideoOutputRouteFeedbacks[outputName];
trilist.OnlineStatusChange += new Crestron.SimplSharpPro.OnlineStatusChangeEventHandler((d, args) =>
{
if (args.DeviceOnLine)
{
foreach (var feedback in Feedbacks)
if (feedback == null)
{
return;
}
var inPort =
InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output].VideoOutFeedback);
var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.HdmiOutputs[output]);
feedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.AudioVideo));
}
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
{
switch (args.EventId)
{
case DMInputEventIds.VideoDetectedEventId:
{
Debug.Console(1, this, "Event ID {0}: Updating VideoInputSyncFeedbacks", args.EventId);
foreach (var item in VideoInputSyncFeedbacks)
{
feedback.FireUpdate();
item.FireUpdate();
}
}
});
}
break;
}
case DMInputEventIds.InputNameFeedbackEventId:
case DMInputEventIds.InputNameEventId:
case DMInputEventIds.NameFeedbackEventId:
{
Debug.Console(1, this, "Event ID {0}: Updating name feedbacks.", args.EventId);
Debug.Console(1, this, "Input {0} Name {1}", args.Number,
_Chassis.HdmiInputs[args.Number].NameFeedback.StringValue);
foreach (var item in InputNameFeedbacks)
{
item.FireUpdate();
}
break;
}
default:
{
Debug.Console(1, this, "Unhandled DM Input Event ID {0}", args.EventId);
break;
}
}
}
#endregion
#region Factory
public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory<HdMdNxM4kEBridgeableController>
{
public HdMdNxM4kEControllerFactory()
{
TypeNames = new List<string>() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device");
var props = JsonConvert.DeserializeObject<HdMdNxM4kEBridgeablePropertiesConfig>(dc.Properties.ToString());
var type = dc.Type.ToLower();
var control = props.Control;
var ipid = control.IpIdInt;
var address = control.TcpSshProperties.Address;
switch (type)
{
case ("hdmd4x14ke-bridgeable"):
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props);
case ("hdmd4x24ke"):
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props);
case ("hdmd6x24ke"):
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props);
default:
return null;
}
}
}
#endregion
#endregion
#region Events
void Chassis_OnlineStatusChange(Crestron.SimplSharpPro.GenericBase currentDevice, Crestron.SimplSharpPro.OnlineOfflineEventArgs args)
{
if (!args.DeviceOnLine) return;
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
_Chassis.Inputs[i].Name.StringValue = InputNames[i];
}
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
_Chassis.Outputs[i].Name.StringValue = OutputNames[i];
}
foreach (var feedback in Feedbacks)
{
feedback.FireUpdate();
}
}
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
{
if (args.EventId != DMOutputEventIds.VideoOutEventId) return;
for (var i = 0; i < VideoOutputRouteFeedbacks.Count; i++)
{
var index = i;
var localInputPort = InputPorts.FirstOrDefault(p => (DMInput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1].VideoOutFeedback);
var localOutputPort =
OutputPorts.FirstOrDefault(p => (DMOutput)p.FeedbackMatchObject == _Chassis.HdmiOutputs[(uint)index + 1]);
VideoOutputRouteFeedbacks[i].FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs((ushort)i, VideoOutputRouteFeedbacks[i].UShortValue, localOutputPort, localInputPort, eRoutingSignalType.AudioVideo));
}
}
void Chassis_DMInputChange(Switch device, DMInputEventArgs args)
{
if (args.EventId != DMInputEventIds.VideoDetectedEventId) return;
foreach (var item in VideoInputSyncFeedbacks)
{
item.FireUpdate();
}
}
#endregion
#region Factory
public class HdMdNxM4kEControllerFactory : EssentialsDeviceFactory<HdMdNxM4kEBridgeableController>
{
public HdMdNxM4kEControllerFactory()
{
TypeNames = new List<string>() { "hdmd4x14ke-bridgeable", "hdmd4x24ke", "hdmd6x24ke" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new HD-MD-NxM-4K-E Device");
var props = JsonConvert.DeserializeObject<HdMdNxM4kEBridgeablePropertiesConfig>(dc.Properties.ToString());
var type = dc.Type.ToLower();
var control = props.Control;
var ipid = control.IpIdInt;
var address = control.TcpSshProperties.Address;
switch (type)
{
case ("hdmd4x14ke-bridgeable"):
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x14kE(ipid, address, Global.ControlSystem), props);
case ("hdmd4x24ke"):
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd4x24kE(ipid, address, Global.ControlSystem), props);
case ("hdmd6x24ke"):
return new HdMdNxM4kEBridgeableController(dc.Key, dc.Name, new HdMd6x24kE(ipid, address, Global.ControlSystem), props);
default:
return null;
}
}
}
#endregion
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DM;
using Newtonsoft.Json;
@@ -13,6 +14,7 @@ using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM.Chassis
{
[Obsolete("Please use HdMdNxM4kEBridgeable Controller")]
public class HdMdNxM4kEController : CrestronGenericBaseDevice, IRoutingInputsOutputs, IRouting
{
public HdMdNxM Chassis { get; private set; }
@@ -31,6 +33,7 @@ namespace PepperDash.Essentials.DM.Chassis
HdMdNxM4kEPropertiesConfig props)
: base(key, name, chassis)
{
Debug.Console(0, this, "Type hdmd4x14ke is obsolete. Please use hdmd4x14ke-bridgeable");
Chassis = chassis;
// logical ports
@@ -43,14 +46,19 @@ namespace PepperDash.Essentials.DM.Chassis
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
OutputPorts.Add(new RoutingOutputPort(DmPortName.HdmiOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this));
// physical settings
if (props != null && props.Inputs != null)
{
var inputRegex = new Regex(@"(?<InputNum>\d)", RegexOptions.IgnoreCase);
foreach (var kvp in props.Inputs)
{
// strip "hdmiIn"
var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
// get numnbers from key and convert to int
//var inputNum = Convert.ToUInt32(kvp.Key.Substring(6));
var inputMatch = inputRegex.Match(kvp.Key);
if (inputMatch == null) continue;
var inputNum = Convert.ToUInt32(inputMatch.Groups["InputNum"].Value);
var port = chassis.HdmiInputs[inputNum].HdmiInputPort;
// set hdcp disables

View File

@@ -1,40 +1,40 @@
using Crestron.SimplSharpPro;
using System;
using System.Linq;
//using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.DM
{
using eVst = eX02VideoSourceType;
using Crestron.SimplSharpPro;
using System;
using System.Linq;
//using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
namespace PepperDash.Essentials.DM
{
using eVst = eX02VideoSourceType;
using eAst = eX02AudioSourceType;
public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback,
IIROutputPorts, IComPorts
{
public DmTx4kz202C Tx { get; private set; }
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
public RoutingOutputPort DmOut { get; private set; }
public RoutingOutputPort HdmiLoopOut { get; private set; }
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
public class DmTx4kz202CController : DmTxControllerBase, ITxRoutingWithFeedback,
IIROutputPorts, IComPorts
{
public DmTx4kz202C Tx { get; private set; }
public RoutingInputPortWithVideoStatuses HdmiIn1 { get; private set; }
public RoutingInputPortWithVideoStatuses HdmiIn2 { get; private set; }
public RoutingOutputPort DmOut { get; private set; }
public RoutingOutputPort HdmiLoopOut { get; private set; }
public override StringFeedback ActiveVideoInputFeedback { get; protected set; }
public IntFeedback VideoSourceNumericFeedback { get; protected set; }
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
public IntFeedback HdmiIn1HdcpCapabilityFeedback { get; protected set; }
public IntFeedback HdmiIn2HdcpCapabilityFeedback { get; protected set; }
public BoolFeedback Hdmi1VideoSyncFeedback { get; protected set; }
public BoolFeedback Hdmi2VideoSyncFeedback { get; protected set; }
//public override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; }
//IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
@@ -47,48 +47,48 @@ namespace PepperDash.Essentials.DM
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
/// <summary>
/// Helps get the "real" inputs, including when in Auto
/// </summary>
public eX02VideoSourceType ActualActiveVideoInput
{
get
{
if (Tx.VideoSourceFeedback != eVst.Auto)
return Tx.VideoSourceFeedback;
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
return eVst.Hdmi1;
return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled;
}
}
public RoutingPortCollection<RoutingInputPort> InputPorts
{
get
{
return new RoutingPortCollection<RoutingInputPort>
{
HdmiIn1,
HdmiIn2,
AnyVideoInput
};
}
}
public RoutingPortCollection<RoutingOutputPort> OutputPorts
{
get
{
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
}
}
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
: base(key, name, tx)
{
}
/// <summary>
/// Helps get the "real" inputs, including when in Auto
/// </summary>
public eX02VideoSourceType ActualActiveVideoInput
{
get
{
if (Tx.VideoSourceFeedback != eVst.Auto)
return Tx.VideoSourceFeedback;
if (Tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
return eVst.Hdmi1;
return Tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue ? eVst.Hdmi2 : eVst.AllDisabled;
}
}
public RoutingPortCollection<RoutingInputPort> InputPorts
{
get
{
return new RoutingPortCollection<RoutingInputPort>
{
HdmiIn1,
HdmiIn2,
AnyVideoInput
};
}
}
public RoutingPortCollection<RoutingOutputPort> OutputPorts
{
get
{
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
}
}
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx)
: base(key, name, tx)
{
Tx = tx;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
@@ -104,208 +104,208 @@ namespace PepperDash.Essentials.DM
FeedbackMatchObject = eVst.Hdmi2
};
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString());
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
//Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
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);
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
(ActualActiveVideoInput == eVst.Hdmi1
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
HdcpStateFeedbackFunc = () =>
{
if (ActualActiveVideoInput == eVst.Hdmi1)
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
if (ActualActiveVideoInput == eVst.Hdmi2)
return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
return "";
},
VideoResolutionFeedbackFunc = () =>
{
if (ActualActiveVideoInput == eVst.Hdmi1)
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
if (ActualActiveVideoInput == eVst.Hdmi2)
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
return "";
},
VideoSyncFeedbackFunc = () =>
(ActualActiveVideoInput == eVst.Hdmi1
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
};
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.DmCat, null, this);
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback);
// Set Ports for CEC
HdmiIn1.Port = Tx.HdmiInputs[1];
HdmiIn2.Port = Tx.HdmiInputs[2];
HdmiLoopOut.Port = Tx.HdmiOutput;
DmOut.Port = Tx.DmOutput;
}
public override bool CustomActivate()
{
// Link up all of these damned events to the various RoutingPorts via a helper handler
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
// Base does register and sets up comm monitoring.
return base.CustomActivate();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
if (Hdmi1VideoSyncFeedback != null)
{
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
}
if (Hdmi2VideoSyncFeedback != null)
{
Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
}
LinkDmTxToApi(this, trilist, joinMap, bridge);
}
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
switch (type)
{
case eRoutingSignalType.Video:
switch (input)
{
case 0:
{
ExecuteSwitch(eVst.Auto, null, type);
break;
}
case 1:
{
ExecuteSwitch(HdmiIn1.Selector, null, type);
break;
}
case 2:
{
ExecuteSwitch(HdmiIn2.Selector, null, type);
break;
}
case 3:
{
ExecuteSwitch(eVst.AllDisabled, null, type);
break;
}
}
break;
case eRoutingSignalType.Audio:
switch (input)
{
case 0:
{
ExecuteSwitch(eAst.Auto, null, type);
break;
}
case 1:
{
ExecuteSwitch(eAst.Hdmi1, null, type);
break;
}
case 2:
{
ExecuteSwitch(eAst.Hdmi2, null, type);
break;
}
case 3:
{
ExecuteSwitch(eAst.AllDisabled, null, type);
break;
}
}
break;
}
}
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
if ((signalType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
Tx.VideoSource = (eVst)inputSelector;
if(((signalType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
}
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
switch (args.EventId)
{
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
break;
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
break;
}
ActiveVideoInputFeedback = new StringFeedback("ActiveVideoInput",
() => ActualActiveVideoInput.ToString());
Tx.HdmiInputs[1].InputStreamChange += InputStreamChangeEvent;
Tx.HdmiInputs[2].InputStreamChange += InputStreamChangeEvent;
Tx.BaseEvent += Tx_BaseEvent;
Tx.OnlineStatusChange += Tx_OnlineStatusChange;
VideoSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
//Return VideoSourceFeedback here as DM-TX-4KZ-202-C does not support audio breakaway
AudioSourceNumericFeedback = new IntFeedback(() => (int)Tx.VideoSourceFeedback);
HdmiIn1HdcpCapabilityFeedback = new IntFeedback("HdmiIn1HdcpCapability", () => (int)tx.HdmiInputs[1].HdcpCapabilityFeedback);
HdmiIn2HdcpCapabilityFeedback = new IntFeedback("HdmiIn2HdcpCapability", () => (int)tx.HdmiInputs[2].HdcpCapabilityFeedback);
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);
var combinedFuncs = new VideoStatusFuncsWrapper
{
HdcpActiveFeedbackFunc = () =>
(ActualActiveVideoInput == eVst.Hdmi1
&& tx.HdmiInputs[1].VideoAttributes.HdcpActiveFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].VideoAttributes.HdcpActiveFeedback.BoolValue),
HdcpStateFeedbackFunc = () =>
{
if (ActualActiveVideoInput == eVst.Hdmi1)
return tx.HdmiInputs[1].VideoAttributes.HdcpStateFeedback.ToString();
if (ActualActiveVideoInput == eVst.Hdmi2)
return tx.HdmiInputs[2].VideoAttributes.HdcpStateFeedback.ToString();
return "";
},
VideoResolutionFeedbackFunc = () =>
{
if (ActualActiveVideoInput == eVst.Hdmi1)
return tx.HdmiInputs[1].VideoAttributes.GetVideoResolutionString();
if (ActualActiveVideoInput == eVst.Hdmi2)
return tx.HdmiInputs[2].VideoAttributes.GetVideoResolutionString();
return "";
},
VideoSyncFeedbackFunc = () =>
(ActualActiveVideoInput == eVst.Hdmi1
&& tx.HdmiInputs[1].SyncDetectedFeedback.BoolValue)
|| (ActualActiveVideoInput == eVst.Hdmi2
&& tx.HdmiInputs[2].SyncDetectedFeedback.BoolValue)
};
AnyVideoInput = new RoutingInputPortWithVideoStatuses(DmPortName.AnyVideoIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.None, 0, this, combinedFuncs);
DmOut = new RoutingOutputPort(DmPortName.DmOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.DmCat, null, this);
HdmiLoopOut = new RoutingOutputPort(DmPortName.HdmiLoopOut, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this);
AddToFeedbackList(ActiveVideoInputFeedback, VideoSourceNumericFeedback, AudioSourceNumericFeedback,
AnyVideoInput.VideoStatus.HasVideoStatusFeedback, AnyVideoInput.VideoStatus.HdcpActiveFeedback,
AnyVideoInput.VideoStatus.HdcpStateFeedback, AnyVideoInput.VideoStatus.VideoResolutionFeedback,
AnyVideoInput.VideoStatus.VideoSyncFeedback, HdmiIn1HdcpCapabilityFeedback, HdmiIn2HdcpCapabilityFeedback,
Hdmi1VideoSyncFeedback, Hdmi2VideoSyncFeedback);
// Set Ports for CEC
HdmiIn1.Port = Tx.HdmiInputs[1];
HdmiIn2.Port = Tx.HdmiInputs[2];
HdmiLoopOut.Port = Tx.HdmiOutput;
DmOut.Port = Tx.DmOutput;
}
public override bool CustomActivate()
{
// Link up all of these damned events to the various RoutingPorts via a helper handler
Tx.HdmiInputs[1].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn1, a.EventId);
Tx.HdmiInputs[1].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn1, a.EventId);
Tx.HdmiInputs[2].InputStreamChange += (o, a) => FowardInputStreamChange(HdmiIn2, a.EventId);
Tx.HdmiInputs[2].VideoAttributes.AttributeChange += (o, a) => ForwardVideoAttributeChange(HdmiIn2, a.EventId);
// Base does register and sets up comm monitoring.
return base.CustomActivate();
}
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = GetDmTxJoinMap(joinStart, joinMapKey);
if (Hdmi1VideoSyncFeedback != null)
{
Hdmi1VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input1VideoSyncStatus.JoinNumber]);
}
if (Hdmi2VideoSyncFeedback != null)
{
Hdmi2VideoSyncFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Input2VideoSyncStatus.JoinNumber]);
}
LinkDmTxToApi(this, trilist, joinMap, bridge);
}
public void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
switch (type)
{
case eRoutingSignalType.Video:
switch (input)
{
case 0:
{
ExecuteSwitch(eVst.Auto, null, type);
break;
}
case 1:
{
ExecuteSwitch(HdmiIn1.Selector, null, type);
break;
}
case 2:
{
ExecuteSwitch(HdmiIn2.Selector, null, type);
break;
}
case 3:
{
ExecuteSwitch(eVst.AllDisabled, null, type);
break;
}
}
break;
case eRoutingSignalType.Audio:
switch (input)
{
case 0:
{
ExecuteSwitch(eAst.Auto, null, type);
break;
}
case 1:
{
ExecuteSwitch(eAst.Hdmi1, null, type);
break;
}
case 2:
{
ExecuteSwitch(eAst.Hdmi2, null, type);
break;
}
case 3:
{
ExecuteSwitch(eAst.AllDisabled, null, type);
break;
}
}
break;
}
}
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
if ((signalType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
Tx.VideoSource = (eVst)inputSelector;
if(((signalType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
Debug.Console(2, this, "Unable to execute audio-only switch for tx {0}", Key);
}
void InputStreamChangeEvent(EndpointInputStream inputStream, EndpointInputStreamEventArgs args)
{
Debug.Console(2, "{0} event {1} stream {2}", Tx.ToString(), inputStream.ToString(), args.EventId.ToString());
switch (args.EventId)
{
case EndpointInputStreamEventIds.HdcpSupportOffFeedbackEventId:
case EndpointInputStreamEventIds.HdcpSupportOnFeedbackEventId:
case EndpointInputStreamEventIds.HdcpCapabilityFeedbackEventId:
if (inputStream == Tx.HdmiInputs[1]) HdmiIn1HdcpCapabilityFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) HdmiIn2HdcpCapabilityFeedback.FireUpdate();
break;
case EndpointInputStreamEventIds.SyncDetectedFeedbackEventId:
if (inputStream == Tx.HdmiInputs[1]) Hdmi1VideoSyncFeedback.FireUpdate();
if (inputStream == Tx.HdmiInputs[2]) Hdmi2VideoSyncFeedback.FireUpdate();
break;
}
}
void Tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
@@ -313,7 +313,7 @@ namespace PepperDash.Essentials.DM
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
@@ -338,68 +338,68 @@ namespace PepperDash.Essentials.DM
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.VideoSourceFeedback);
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;
}
}
/// <summary>
/// Relays the input stream change to the appropriate RoutingInputPort.
/// </summary>
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
{
return;
}
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
}
/// <summary>
/// Relays the VideoAttributes change to a RoutingInputPort
/// </summary>
void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
//// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
//Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
// args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
switch (eventId)
{
case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HdcpStateFeedbackEventId:
inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
}
}
#region IIROutputPorts Members
public CrestronCollection<IROutputPort> IROutputPorts { get { return Tx.IROutputPorts; } }
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
#endregion
#region IComPorts Members
public CrestronCollection<ComPort> ComPorts { get { return Tx.ComPorts; } }
public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
#endregion
}
}
/// <summary>
/// Relays the input stream change to the appropriate RoutingInputPort.
/// </summary>
void FowardInputStreamChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
if (eventId != EndpointInputStreamEventIds.SyncDetectedFeedbackEventId)
{
return;
}
inputPort.VideoStatus.VideoSyncFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoSyncFeedback.FireUpdate();
}
/// <summary>
/// Relays the VideoAttributes change to a RoutingInputPort
/// </summary>
void ForwardVideoAttributeChange(RoutingInputPortWithVideoStatuses inputPort, int eventId)
{
//// LOCATION: Crestron.SimplSharpPro.DM.VideoAttributeEventIds
//Debug.Console(2, this, "VideoAttributes_AttributeChange event id={0} from {1}",
// args.EventId, (sender as VideoAttributesEnhanced).Owner.GetType());
switch (eventId)
{
case VideoAttributeEventIds.HdcpActiveFeedbackEventId:
inputPort.VideoStatus.HdcpActiveFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpActiveFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HdcpStateFeedbackEventId:
inputPort.VideoStatus.HdcpStateFeedback.FireUpdate();
AnyVideoInput.VideoStatus.HdcpStateFeedback.FireUpdate();
break;
case VideoAttributeEventIds.HorizontalResolutionFeedbackEventId:
case VideoAttributeEventIds.VerticalResolutionFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
case VideoAttributeEventIds.FramesPerSecondFeedbackEventId:
inputPort.VideoStatus.VideoResolutionFeedback.FireUpdate();
AnyVideoInput.VideoStatus.VideoResolutionFeedback.FireUpdate();
break;
}
}
#region IIROutputPorts Members
public CrestronCollection<IROutputPort> IROutputPorts { get { return Tx.IROutputPorts; } }
public int NumberOfIROutputPorts { get { return Tx.NumberOfIROutputPorts; } }
#endregion
#region IComPorts Members
public CrestronCollection<ComPort> ComPorts { get { return Tx.ComPorts; } }
public int NumberOfComPorts { get { return Tx.NumberOfComPorts; } }
#endregion
}
}

View File

@@ -339,7 +339,7 @@ namespace PepperDash.Essentials.DM
var localVideoInputPort =
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
var localAudioInputPort =
InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
ActiveVideoInputFeedback.FireUpdate();
VideoSourceNumericFeedback.FireUpdate();
@@ -364,8 +364,8 @@ namespace PepperDash.Essentials.DM
OnSwitchChange(new RoutingNumericEventArgs(1, VideoSourceNumericFeedback.UShortValue, OutputPorts.First(), localVideoInputPort, eRoutingSignalType.Video));
break;
case EndpointTransmitterBase.AudioSourceFeedbackEventId:
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eAst)p.Selector == Tx.AudioSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.AudioSourceFeedback);
var localInputAudioPort = InputPorts.FirstOrDefault(p => (eVst)p.Selector == Tx.VideoSourceFeedback);
Debug.Console(2, this, " Audio Source: {0}", Tx.VideoSourceFeedback);
AudioSourceNumericFeedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(1, AudioSourceNumericFeedback.UShortValue, OutputPorts.First(), localInputAudioPort, eRoutingSignalType.Audio));
break;

View File

@@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.AudioCodec
/// <summary>
/// For rooms that have audio codec
/// </summary>
public interface IHasAudioCodec
public interface IHasAudioCodec:IHasInCallFeedback
{
AudioCodecBase AudioCodec { get; }
BoolFeedback InCallFeedback { get; }
///// <summary>
///// Make this more specific

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.Codec
{
/// <summary>
/// Describes a device that has Do Not Disturb mode capability
/// </summary>
public interface IHasDoNotDisturbMode
{
/// <summary>
/// Indictes whether Do Not Disturb mode is on (Activated)
/// </summary>
BoolFeedback DoNotDisturbModeIsOnFeedback { get; }
/// <summary>
/// Activates Do Not Disturb mode
/// </summary>
void ActivateDoNotDisturbMode();
/// <summary>
/// Deactivates Do Not Disturb mode
/// </summary>
void DeactivateDoNotDisturbMode();
/// <summary>
/// Toggles Do Not Disturb mode
/// </summary>
void ToggleDoNotDisturbMode();
}
public interface IHasDoNotDisturbModeWithTimeout : IHasDoNotDisturbMode
{
/// <summary>
/// Activates Do Not Disturb mode with a timeout
/// </summary>
/// <param name="timeout"></param>
void ActivateDoNotDisturbMode(int timeout);
}
}

View File

@@ -160,7 +160,19 @@ namespace PepperDash.Essentials.Devices.Common.Codec
/// </summary>
public interface IInvitableContact
{
bool IsInvitableContact { get; }
}
public class InvitableDirectoryContact : DirectoryContact, IInvitableContact
{
[JsonProperty("isInvitableContact")]
public bool IsInvitableContact
{
get
{
return this is IInvitableContact;
}
}
}
/// <summary>
@@ -209,8 +221,6 @@ namespace PepperDash.Essentials.Devices.Common.Codec
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("contactMethods")]
public List<ContactMethod> ContactMethods { get; set; }

View File

@@ -235,6 +235,15 @@ namespace PepperDash.Essentials.Devices.Common.Codec
{
Calls = new List<Call>();
}
#region Overrides of Object
public override string ToString()
{
return String.Format("{0}:{1}: {2}-{3}", Title, Agenda, StartTime, EndTime);
}
#endregion
}
public class Call

View File

@@ -108,6 +108,7 @@
<Compile Include="Codec\eCodecCallStatus.cs" />
<Compile Include="Codec\eMeetingPrivacy.cs" />
<Compile Include="Codec\iCodecAudio.cs" />
<Compile Include="Codec\IHasDoNotDisturb.cs" />
<Compile Include="Codec\IHasExternalSourceSwitching.cs" />
<Compile Include="ImageProcessors\TVOneCorio.cs" />
<Compile Include="ImageProcessors\TVOneCorioPropertiesConfig.cs" />
@@ -117,12 +118,17 @@
<Compile Include="ImageProcessors\AnalogWay\AnalogWayLiveCorePropertiesConfig.cs" />
<Compile Include="SoftCodec\BlueJeansPc.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCamera.cs" />
<Compile Include="VideoCodec\CiscoCodec\CiscoCodecJoinMap.cs" />
<Compile Include="VideoCodec\CiscoCodec\RoomPresets.cs" />
<Compile Include="Cameras\CameraControl.cs" />
<Compile Include="Display\PanasonicThDisplay.cs" />
<Compile Include="VideoCodec\Interfaces\IHasMeetingInfo.cs" />
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
<Compile Include="VideoCodec\Interfaces\IHasPresentationOnlyMeeting.cs" />
<Compile Include="VideoCodec\Interfaces\IHasSelfviewPosition.cs" />
<Compile Include="VideoCodec\Interfaces\IHasSelfviewSize.cs" />
<Compile Include="VideoCodec\Interfaces\IHasStandbyMode.cs" />
<Compile Include="VideoCodec\Interfaces\IHasStartMeeting.cs" />
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
<Compile Include="Codec\iHasCallFavorites.cs" />
<Compile Include="Codec\iHasCallHistory.cs" />

View File

@@ -0,0 +1,120 @@
using System;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges.JoinMaps;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{
public class CiscoCodecJoinMap : VideoCodecControllerJoinMap
{
#region Digital
[JoinName("ActivateDoNotDisturbMode")]
public JoinDataComplete ActivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 221,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Activates Do Not Disturb Mode. FB High if active.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DeactivateDoNotDisturbMode")]
public JoinDataComplete DeactivateDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 222,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Deactivates Do Not Disturb Mode. FB High if deactivated.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ToggleDoNotDisturbMode")]
public JoinDataComplete ToggleDoNotDisturbMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 223,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Toggles Do Not Disturb Mode.",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ActivateStandby")]
public JoinDataComplete ActivateStandby = new JoinDataComplete(
new JoinData
{
JoinNumber = 226,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Activates Standby Mode. FB High if active.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("DeactivateStandby")]
public JoinDataComplete DeactivateStandby = new JoinDataComplete(
new JoinData
{
JoinNumber = 227,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Deactivates Standby Mode. FB High if deactivated.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
[JoinName("ActivateHalfWakeMode")]
public JoinDataComplete ActivateHalfWakeMode = new JoinDataComplete(
new JoinData
{
JoinNumber = 228,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Activates Half Wake Mode. FB High if active.",
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
JoinType = eJoinType.Digital
});
#endregion
#region Analog
#endregion
#region Serials
#endregion
public CiscoCodecJoinMap(uint joinStart)
: base(joinStart, typeof(CiscoCodecJoinMap))
{
}
public CiscoCodecJoinMap(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View File

@@ -28,7 +28,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectoryHistoryStack,
IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView,
ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute
ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets,
IHasExternalSourceSwitching, IHasBranding, IHasCameraOff, IHasCameraMute, IHasDoNotDisturbMode,
IHasHalfWakeMode
{
private bool _externalSourceChangeRequested;
@@ -326,6 +328,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CameraIsMutedFeedback = CameraIsOffFeedback;
SupportsCameraOff = true;
DoNotDisturbModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Conference.DoNotDisturb.BoolValue);
HalfWakeModeIsOnFeedback = new BoolFeedback(() => CodecStatus.Status.Standby.State.Value == "Halfwake");
PresentationViewMaximizedFeedback = new BoolFeedback(() => CurrentPresentationView == "Maximized");
Communication = comm;
@@ -422,7 +427,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CodecStatus.Status.Audio.Volume.ValueChangedAction = VolumeLevelFeedback.FireUpdate;
CodecStatus.Status.Audio.VolumeMute.ValueChangedAction = MuteFeedback.FireUpdate;
CodecStatus.Status.Audio.Microphones.Mute.ValueChangedAction = PrivacyModeIsOnFeedback.FireUpdate;
CodecStatus.Status.Standby.State.ValueChangedAction = StandbyIsOnFeedback.FireUpdate;
CodecStatus.Status.Standby.State.ValueChangedAction = new Action(() =>
{
StandbyIsOnFeedback.FireUpdate();
HalfWakeModeIsOnFeedback.FireUpdate();
});
CodecStatus.Status.RoomAnalytics.PeoplePresence.ValueChangedAction = RoomIsOccupiedFeedback.FireUpdate;
CodecStatus.Status.RoomAnalytics.PeopleCount.Current.ValueChangedAction = PeopleCountFeedback.FireUpdate;
CodecStatus.Status.Cameras.SpeakerTrack.Status.ValueChangedAction = CameraAutoModeIsOnFeedback.FireUpdate;
@@ -432,6 +441,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;
CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = SharingContentIsOnFeedback.FireUpdate;
CodecStatus.Status.Conference.Presentation.Mode.ValueChangedAction = FarEndIsSharingContentFeedback.FireUpdate;
CodecStatus.Status.Conference.DoNotDisturb.ValueChangedAction = DoNotDisturbModeIsOnFeedback.FireUpdate;
try
{
CodecStatus.Status.Video.Input.MainVideoMute.ValueChangedAction = CameraIsOffFeedback.FireUpdate;
@@ -584,6 +595,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
prefix + "/Status/Audio" + Delimiter +
prefix + "/Status/Call" + Delimiter +
prefix + "/Status/Conference/Presentation" + Delimiter +
prefix + "/Status/Conference/DoNotDisturb" + Delimiter +
prefix + "/Status/Cameras/SpeakerTrack" + Delimiter +
prefix + "/Status/RoomAnalytics" + Delimiter +
prefix + "/Status/RoomPreset" + Delimiter +
@@ -592,10 +604,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
prefix + "/Status/Video/Layout" + Delimiter +
prefix + "/Status/Video/Input/MainVideoMute" + Delimiter +
prefix + "/Bookings" + Delimiter +
prefix + "/Event/CallDisconnect" + Delimiter +
prefix + "/Event/Bookings" + Delimiter +
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter +
prefix + "/Event/CallDisconnect" + Delimiter; // Keep CallDisconnect last to detect when feedback registration completes correctly
}
#endregion
@@ -752,6 +765,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
}
/// <summary>
/// Appends the delimiter and send the command to the codec
/// </summary>
/// <param name="command"></param>
public void SendText(string command)
{
if (CommDebuggingIsOn)
@@ -1490,7 +1507,49 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new CiscoCodecJoinMap(joinStart);
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
if (customJoins != null)
{
joinMap.SetCustomJoinData(customJoins);
}
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge);
LinkCiscoCodecToApi(trilist, joinMap);
}
public void LinkCiscoCodecToApi(BasicTriList trilist, CiscoCodecJoinMap joinMap)
{
var dndCodec = this as IHasDoNotDisturbMode;
if (dndCodec != null)
{
dndCodec.DoNotDisturbModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateDoNotDisturbMode.JoinNumber]);
dndCodec.DoNotDisturbModeIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateDoNotDisturbMode.JoinNumber]);
trilist.SetSigFalseAction(joinMap.ActivateDoNotDisturbMode.JoinNumber, () => dndCodec.ActivateDoNotDisturbMode());
trilist.SetSigFalseAction(joinMap.DeactivateDoNotDisturbMode.JoinNumber, () => dndCodec.DeactivateDoNotDisturbMode());
trilist.SetSigFalseAction(joinMap.ToggleDoNotDisturbMode.JoinNumber, () => dndCodec.ToggleDoNotDisturbMode());
}
var halfwakeCodec = this as IHasHalfWakeMode;
if (halfwakeCodec != null)
{
halfwakeCodec.StandbyIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateStandby.JoinNumber]);
halfwakeCodec.StandbyIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.DeactivateStandby.JoinNumber]);
halfwakeCodec.HalfWakeModeIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.ActivateHalfWakeMode.JoinNumber]);
trilist.SetSigFalseAction(joinMap.ActivateStandby.JoinNumber, () => halfwakeCodec.StandbyActivate());
trilist.SetSigFalseAction(joinMap.DeactivateStandby.JoinNumber, () => halfwakeCodec.StandbyDeactivate());
trilist.SetSigFalseAction(joinMap.ActivateHalfWakeMode.JoinNumber, () => halfwakeCodec.HalfwakeActivate());
}
}
/// <summary>
@@ -2074,6 +2133,45 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
else
CameraMuteOn();
}
#region IHasDoNotDisturbMode Members
public BoolFeedback DoNotDisturbModeIsOnFeedback { get; private set; }
public void ActivateDoNotDisturbMode()
{
SendText("xCommand Conference DoNotDisturb Activate");
}
public void DeactivateDoNotDisturbMode()
{
SendText("xCommand Conference DoNotDisturb Deactivate");
}
public void ToggleDoNotDisturbMode()
{
if (DoNotDisturbModeIsOnFeedback.BoolValue)
{
DeactivateDoNotDisturbMode();
}
else
{
ActivateDoNotDisturbMode();
}
}
#endregion
#region IHasHalfWakeMode Members
public BoolFeedback HalfWakeModeIsOnFeedback { get; private set; }
public void HalfwakeActivate()
{
SendText("xCommand Standby Halfwake");
}
#endregion
}

View File

@@ -440,9 +440,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public CallId CallId { get; set; }
}
public class DoNotDisturb
public class DoNotDisturb : ValueProperty
{
public string Value { get; set; }
string _Value;
public bool BoolValue { get; private set; }
public string Value
{
get
{
return _Value;
}
set
{
_Value = value;
// If the incoming value is "On" it sets the BoolValue true, otherwise sets it false
BoolValue = value == "On" || value == "Active";
OnValueChanged();
}
}
}
public class Mode
@@ -600,6 +617,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Conference2()
{
Presentation = new Presentation();
DoNotDisturb = new DoNotDisturb();
}
}
@@ -1380,12 +1398,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public class State : ValueProperty
{
string _value;
public bool BoolValue { get; private set; }
public string Value // Valid values are Standby/EnteringStandby/Halfwake/Off
{
get { return _value; }
set
{
_value = value;
// If the incoming value is "On" it sets the BoolValue true, otherwise sets it false
BoolValue = value == "On" || value == "Standby";
OnValueChanged();
@@ -2091,6 +2113,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Conference = new Conference2();
SystemUnit = new SystemUnit();
Video = new Video();
Conference = new Conference2();
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Describes a device that provides meeting information (like a ZoomRoom)
/// </summary>
public interface IHasMeetingInfo
{
event EventHandler<MeetingInfoEventArgs> MeetingInfoChanged;
MeetingInfo MeetingInfo { get; }
}
/// <summary>
/// Represents the information about a meeting in progress
/// Currently used for Zoom meetings
/// </summary>
public class MeetingInfo
{
[JsonProperty("id")]
public string Id { get; private set; }
[JsonProperty("name")]
public string Name { get; private set; }
[JsonProperty("host")]
public string Host { get; private set; }
[JsonProperty("password")]
public string Password { get; private set; }
[JsonProperty("shareStatus")]
public string ShareStatus { get; private set; }
[JsonProperty("isHost")]
public Boolean IsHost { get; private set; }
[JsonProperty("isSharingMeeting")]
public Boolean IsSharingMeeting { get; private set; }
[JsonProperty("waitingForHost")]
public Boolean WaitingForHost { get; private set; }
public MeetingInfo(string id, string name, string host, string password, string shareStatus, bool isHost, bool isSharingMeeting, bool waitingForHost)
{
Id = id;
Name = name;
Host = host;
Password = password;
ShareStatus = shareStatus;
IsHost = isHost;
IsSharingMeeting = isSharingMeeting;
WaitingForHost = waitingForHost;
}
}
public class MeetingInfoEventArgs : EventArgs
{
public MeetingInfo Info { get; private set; }
public MeetingInfoEventArgs(MeetingInfo info)
{
Info = info;
}
}
}

View File

@@ -1,100 +1,112 @@
using System;
using System.Linq;
using System.Collections.Generic;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Describes a device that has call participants
/// </summary>
public interface IHasParticipants
{
CodecParticipants Participants { get; }
}
/// <summary>
/// Describes a device that has call participants
/// </summary>
public interface IHasParticipants
{
CodecParticipants Participants { get; }
}
/// <summary>
/// Describes the ability to mute and unmute a participant's video in a meeting
/// </summary>
public interface IHasParticipantVideoMute:IHasParticipants
{
void MuteVideoForParticipant(int userId);
void UnmuteVideoForParticipant(int userId);
void ToggleVideoForParticipant(int userId);
}
/// <summary>
/// Describes the ability to mute and unmute a participant's video in a meeting
/// </summary>
public interface IHasParticipantVideoMute : IHasParticipants
{
void MuteVideoForParticipant(int userId);
void UnmuteVideoForParticipant(int userId);
void ToggleVideoForParticipant(int userId);
}
/// <summary>
/// Describes the ability to mute and unmute a participant's audio in a meeting
/// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{
void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId);
}
/// <summary>
/// Describes the ability to mute and unmute a participant's audio in a meeting
/// </summary>
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
{
void MuteAudioForParticipant(int userId);
void UnmuteAudioForParticipant(int userId);
void ToggleAudioForParticipant(int userId);
}
/// <summary>
/// Describes the ability to pin and unpin a participant in a meeting
/// </summary>
public interface IHasParticipantPinUnpin : IHasParticipants
{
IntFeedback NumberOfScreensFeedback { get; }
int ScreenIndexToPinUserTo { get; }
/// <summary>
/// Describes the ability to pin and unpin a participant in a meeting
/// </summary>
public interface IHasParticipantPinUnpin : IHasParticipants
{
IntFeedback NumberOfScreensFeedback { get; }
int ScreenIndexToPinUserTo { get; }
void PinParticipant(int userId, int screenIndex);
void UnPinParticipant(int userId);
void ToggleParticipantPinState(int userId, int screenIndex);
}
void PinParticipant(int userId, int screenIndex);
void UnPinParticipant(int userId);
void ToggleParticipantPinState(int userId, int screenIndex);
}
public class CodecParticipants
{
private List<Participant> _currentParticipants;
public List<Participant> CurrentParticipants {
get { return _currentParticipants; }
set
public class CodecParticipants
{
private List<Participant> _currentParticipants;
public List<Participant> CurrentParticipants
{
get { return _currentParticipants; }
set
{
_currentParticipants = value;
OnParticipantsChanged();
}
}
public Participant Host
{
get
{
_currentParticipants = value;
OnParticipantsChanged();
return _currentParticipants.FirstOrDefault(p => p.IsHost);
}
}
public event EventHandler<EventArgs> ParticipantsListHasChanged;
public event EventHandler<EventArgs> ParticipantsListHasChanged;
public CodecParticipants()
{
_currentParticipants = new List<Participant>();
}
public CodecParticipants()
{
_currentParticipants = new List<Participant>();
}
public void OnParticipantsChanged()
{
var handler = ParticipantsListHasChanged;
public void OnParticipantsChanged()
{
var handler = ParticipantsListHasChanged;
if (handler == null) return;
if (handler == null) return;
handler(this, new EventArgs());
}
}
handler(this, new EventArgs());
}
}
/// <summary>
/// Represents a call participant
/// </summary>
public class Participant
{
public int UserId { get; set; }
public bool IsHost { get; set; }
public string Name { get; set; }
public bool CanMuteVideo { get; set; }
public bool CanUnmuteVideo { get; set; }
public bool VideoMuteFb { get; set; }
public bool AudioMuteFb { get; set; }
public bool HandIsRaisedFb { get; set; }
public bool IsPinnedFb { get; set; }
public int ScreenIndexIsPinnedToFb { get; set; }
/// <summary>
/// Represents a call participant
/// </summary>
public class Participant
{
public int UserId { get; set; }
public bool IsHost { get; set; }
public bool IsMyself { get; set; }
public string Name { get; set; }
public bool CanMuteVideo { get; set; }
public bool CanUnmuteVideo { get; set; }
public bool VideoMuteFb { get; set; }
public bool AudioMuteFb { get; set; }
public bool HandIsRaisedFb { get; set; }
public bool IsPinnedFb { get; set; }
public int ScreenIndexIsPinnedToFb { get; set; }
public Participant()
{
// Initialize to -1 (no screen)
ScreenIndexIsPinnedToFb = -1;
}
}
public Participant()
{
// Initialize to -1 (no screen)
ScreenIndexIsPinnedToFb = -1;
}
}
}

View File

@@ -0,0 +1,18 @@
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
public interface IHasPresentationOnlyMeeting
{
void StartSharingOnlyMeeting();
void StartSharingOnlyMeeting(eSharingMeetingMode mode);
void StartSharingOnlyMeeting(eSharingMeetingMode mode, ushort duration);
void StartSharingOnlyMeeting(eSharingMeetingMode mode, ushort duration, string password);
void StartNormalMeetingFromSharingOnlyMeeting();
}
public enum eSharingMeetingMode
{
None,
Laptop,
Ios,
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
/// <summary>
/// Describes a device that has Standby Mode capability
/// </summary>
public interface IHasStandbyMode
{
BoolFeedback StandbyIsOnFeedback { get; }
void StandbyActivate();
void StandbyDeactivate();
}
/// <summary>
/// Describes a device that has Half Waek Mode capability
/// </summary>
public interface IHasHalfWakeMode : IHasStandbyMode
{
BoolFeedback HalfWakeModeIsOnFeedback { get; }
void HalfwakeActivate();
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
{
/// <summary>
/// Describes the ability to start an ad-hoc meeting
/// </summary>
public interface IHasStartMeeting
{
/// <summary>
/// The default meeting duration in minutes
/// </summary>
uint DefaultMeetingDurationMin { get; }
/// <summary>
/// Start an ad-hoc meeting for the specified duration
/// </summary>
/// <param name="duration"></param>
void StartMeeting(uint duration);
/// <summary>
/// Leaves a meeting without ending it
/// </summary>
void LeaveMeeting();
}
}

View File

@@ -11,10 +11,9 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// <summary>
/// For rooms that have video codec
/// </summary>
public interface IHasVideoCodec
public interface IHasVideoCodec:IHasInCallFeedback,IPrivacy
{
VideoCodecBase VideoCodec { get; }
BoolFeedback InCallFeedback { get; }
///// <summary>
///// Make this more specific
@@ -26,11 +25,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// </summary>
IntFeedback CallTypeFeedback { get; }
/// <summary>
///
/// </summary>
BoolFeedback PrivacyModeIsOnFeedback { get; }
/// <summary>
/// When something in the room is sharing with the far end or through other means
/// </summary>

View File

@@ -123,12 +123,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
/// Creates the fake OSD source, and connects it's AudioVideo output to the CodecOsdIn input
/// to enable routing
/// </summary>
void CreateOsdSource()
private void CreateOsdSource()
{
OsdSource = new DummyRoutingInputsDevice(Key + "[osd]");
DeviceManager.AddDevice(OsdSource);
var tl = new TieLine(OsdSource.AudioVideoOutputPort, CodecOsdIn);
TieLineCollection.Default.Add(tl);
//foreach(var input in Status.Video.
}
/// <summary>
@@ -580,6 +582,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
void SetupCameras()
{
SupportsCameraAutoMode = true;
SupportsCameraOff = false;
Cameras = new List<CameraBase>();
var internalCamera = new MockVCCamera(Key + "-camera1", "Near End", this);

View File

@@ -25,7 +25,7 @@ using Feedback = PepperDash.Essentials.Core.Feedback;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public abstract class VideoCodecBase : ReconfigurableDevice, IRoutingInputsOutputs,
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced, IHasStandbyMode
{
private const int XSigEncoding = 28591;
protected const int MaxParticipants = 50;
@@ -836,10 +836,10 @@ ScreenIndexIsPinnedTo: {8} (a{17})
//serials
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, meeting.Organizer);
tokenArray[stringIndex + 1] = new XSigSerialToken(stringIndex + 2, meeting.Title);
tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToShortDateString());
tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToShortTimeString());
tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToShortDateString());
tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToShortTimeString());
tokenArray[stringIndex + 2] = new XSigSerialToken(stringIndex + 3, meeting.StartTime.ToString("t", Global.Culture));
tokenArray[stringIndex + 3] = new XSigSerialToken(stringIndex + 4, meeting.StartTime.ToString("t", Global.Culture));
tokenArray[stringIndex + 4] = new XSigSerialToken(stringIndex + 5, meeting.EndTime.ToString("t", Global.Culture));
tokenArray[stringIndex + 5] = new XSigSerialToken(stringIndex + 6, meeting.EndTime.ToString("t", Global.Culture));
tokenArray[stringIndex + 6] = new XSigSerialToken(stringIndex + 7, meeting.Id);

View File

@@ -59,6 +59,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public List<zStatus.AudioVideoInputOutputLineItem> AudioOuputs { get; set; }
public List<zStatus.AudioVideoInputOutputLineItem> Cameras { get; set; }
public zEvent.PhoneCallStatus PhoneCall { get; set; }
public zEvent.NeedWaitForHost NeedWaitForHost { get; set; }
public ZoomRoomStatus()
{
@@ -76,6 +77,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
AudioOuputs = new List<zStatus.AudioVideoInputOutputLineItem>();
Cameras = new List<zStatus.AudioVideoInputOutputLineItem>();
PhoneCall = new zEvent.PhoneCallStatus();
NeedWaitForHost = new zEvent.NeedWaitForHost();
}
}
@@ -236,14 +238,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
}
/// <summary>
/// Used to be able to inplement IInvitableContact on DirectoryContact
/// </summary>
public class ZoomDirectoryContact : DirectoryContact, IInvitableContact
{
}
public class Phonebook
{
[JsonProperty("Contacts")]
@@ -302,7 +296,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
foreach (Contact c in zoomContacts)
{
var contact = new ZoomDirectoryContact { Name = c.ScreenName, ContactId = c.Jid };
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 });
@@ -439,6 +433,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
{
private string _dispState;
private string _password;
private bool _isAirHostClientConnected;
private bool _isSharingBlackMagic;
private bool _isDirectPresentationConnected;
public string directPresentationPairingCode { get; set; }
/// <summary>
@@ -460,11 +458,51 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
}
}
}
public bool isAirHostClientConnected { get; set; }
public bool isAirHostClientConnected
{
get { return _isAirHostClientConnected; }
set
{
if (value != _isAirHostClientConnected)
{
_isAirHostClientConnected = value;
NotifyPropertyChanged("isAirHostClientConnected");
}
}
}
public bool isBlackMagicConnected { get; set; }
public bool isBlackMagicDataAvailable { get; set; }
public bool isDirectPresentationConnected { get; set; }
public bool isSharingBlackMagic { get; set; }
public bool isDirectPresentationConnected
{
get { return _isDirectPresentationConnected; }
set
{
if (value != _isDirectPresentationConnected)
{
_isDirectPresentationConnected = value;
NotifyPropertyChanged("isDirectPresentationConnected");
}
}
}
public bool isSharingBlackMagic
{
get { return _isSharingBlackMagic; }
set
{
if (value != _isSharingBlackMagic)
{
_isSharingBlackMagic = value;
NotifyPropertyChanged("isSharingBlackMagic");
}
}
}
/// <summary>
/// IOS Airplay code
/// </summary>
@@ -720,6 +758,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
/// </summary>
public class zEvent
{
public class StartLocalPresentMeeting
{
public bool Success { get; set; }
}
public class NeedWaitForHost
{
public bool Wait { get; set; }
@@ -787,7 +829,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
private bool _paused;
private eSharingState _state;
public bool IsSharing;
public bool IsSharing { get; private set; }
[JsonProperty("paused")]
public bool Paused
@@ -927,6 +969,15 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
PhoneCallStatus_InCall,
PhoneCallStatus_Init,
}
public class MeetingNeedsPassword
{
[JsonProperty("needsPassword")]
public bool NeedsPassword { get; set; }
[JsonProperty("wrongAndRetry")]
public bool WrongAndRetry { get; set; }
}
}
/// <summary>
@@ -1426,6 +1477,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
public static List<Participant> GetGenericParticipantListFromParticipantsResult(
List<ListParticipant> participants)
{
if (participants.Count == 0)
{
return new List<Participant>();
}
//return participants.Select(p => new Participant
// {
// UserId = p.UserId,
@@ -1444,6 +1499,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
UserId = p.UserId,
Name = p.UserName,
IsHost = p.IsHost,
IsMyself = p.IsMyself,
CanMuteVideo = p.IsVideoCanMuteByHost,
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",

View File

@@ -25,5 +25,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
//This layout will be selected when a call is connected and no content is being shared
public string DefaultCallLayout { get; set; }
public int MinutesBeforeMeetingStart { get; set; }
}
}