Merge branch 'development' into hotfix/essentials-cooling-routing

This commit is contained in:
Andrew Welker 2022-09-02 11:49:06 -06:00 committed by GitHub
commit 5ba7abb59b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 2954 additions and 775 deletions

View file

@ -53,14 +53,14 @@ namespace PepperDash.Essentials
// to allow any HD-BaseT DM endpoints to register first. // to allow any HD-BaseT DM endpoints to register first.
if (Global.ControlSystemIsDmpsType) if (Global.ControlSystemIsDmpsType)
{ {
Debug.Console(2, "******************* InitializeSystem() Entering **********************"); Debug.Console(1, "******************* InitializeSystem() Entering **********************");
_initializeEvent = new CEvent(); _initializeEvent = new CEvent();
DeviceManager.AllDevicesActivated += (o, a) => DeviceManager.AllDevicesRegistered += (o, a) =>
{ {
_initializeEvent.Set(); _initializeEvent.Set();
Debug.Console(2, "******************* InitializeSystem() Exiting **********************"); Debug.Console(1, "******************* InitializeSystem() Exiting **********************");
}; };
_initializeEvent.Wait(30000); _initializeEvent.Wait(30000);
@ -490,21 +490,17 @@ namespace PepperDash.Essentials
} }
} }
AddRoomAndBuildMC(room);
if (room is IEssentialsHuddleSpaceRoom) if (room is IEssentialsHuddleSpaceRoom)
{ {
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
} }
else if (room is IEssentialsHuddleVtc1Room) else if (room is IEssentialsHuddleVtc1Room)
{ {
DeviceManager.AddDevice(room);
if (!(room is EssentialsCombinedHuddleVtc1Room)) if (!(room is EssentialsCombinedHuddleVtc1Room))
{ {
@ -512,28 +508,15 @@ namespace PepperDash.Essentials
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((IEssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
} }
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
CreateMobileControlBridge(room);
} }
else if (room is EssentialsTechRoom) else if (room is EssentialsTechRoom)
{ {
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, Debug.Console(0, Debug.ErrorLogLevel.Notice,
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId); "Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion with IP-ID {0:X2}", fusionIpId);
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey)); DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
CreateMobileControlBridge(room);
} }
else
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion");
DeviceManager.AddDevice(room);
}
fusionIpId += 1; fusionIpId += 1;
} }
else else
@ -547,6 +530,15 @@ namespace PepperDash.Essentials
} }
private static void AddRoomAndBuildMC(IEssentialsRoom room)
{
DeviceManager.AddDevice(room);
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
CreateMobileControlBridge(room);
}
private static void CreateMobileControlBridge(object room) private static void CreateMobileControlBridge(object room)
{ {
var mobileControl = GetMobileControlDevice(); var mobileControl = GetMobileControlDevice();

View file

@ -19,32 +19,41 @@ namespace PepperDash.Essentials.Room.Config
/// Returns a room object from this config data /// Returns a room object from this config data
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static Device GetRoomObject(DeviceConfig roomConfig) public static IKeyed GetRoomObject(DeviceConfig roomConfig)
{ {
var typeName = roomConfig.Type.ToLower(); var typeName = roomConfig.Type.ToLower();
if (typeName == "huddle") switch (typeName)
{
case "huddle" :
{ {
return new EssentialsHuddleSpaceRoom(roomConfig); return new EssentialsHuddleSpaceRoom(roomConfig);
} }
if (typeName == "huddlevtc1") case "huddlevtc1" :
{ {
return new EssentialsHuddleVtc1Room(roomConfig); return new EssentialsHuddleVtc1Room(roomConfig);
} }
if (typeName == "ddvc01bridge") case "ddvc01bridge" :
{ {
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing. return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
} }
if (typeName == "dualdisplay") case "dualdisplay" :
{ {
return new EssentialsDualDisplayRoom(roomConfig); return new EssentialsDualDisplayRoom(roomConfig);
} }
if (typeName == "combinedhuddlevtc1") case "combinedhuddlevtc1" :
{ {
return new EssentialsCombinedHuddleVtc1Room(roomConfig); return new EssentialsCombinedHuddleVtc1Room(roomConfig);
} }
case "techroom" :
return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig); {
return new EssentialsTechRoom(roomConfig);
}
default :
{
return Core.DeviceFactory.GetDevice(roomConfig);
}
}
} }
/// <summary> /// <summary>

View file

@ -24,6 +24,10 @@ namespace PepperDash.Essentials.Core.Bridges
JoinType = eJoinType.Digital JoinType = eJoinType.Digital
}); });
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("SystemId")] [JoinName("SystemId")]
public JoinDataComplete SystemId = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 }, public JoinDataComplete SystemId = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 },
new JoinMetadata { Description = "DM Chassis SystemId Get/Set/Trigger/", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalog }); new JoinMetadata { Description = "DM Chassis SystemId Get/Set/Trigger/", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.DigitalAnalog });

View file

@ -17,6 +17,10 @@ namespace PepperDash.Essentials.Core.Bridges
public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 }, public JoinDataComplete MixerPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog }); new JoinMetadata { Description = "Mixer Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MixerEqPresetRecall")]
public JoinDataComplete MixerEqPresetRecall = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
new JoinMetadata { Description = "Mixer Eq Preset Recall Set", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
[JoinName("MasterVolumeMuteOn")] [JoinName("MasterVolumeMuteOn")]
public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 }, public JoinDataComplete MasterVolumeMuteOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital }); new JoinMetadata { Description = "Master Volume Mute On Set / Get", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });

View file

@ -0,0 +1,60 @@
using System;
namespace PepperDash.Essentials.Core.Bridges
{
public class PduJoinMapBase : JoinMapBaseAdvanced
{
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("Online")]
public JoinDataComplete Online = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "PDU Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletCount")]
public JoinDataComplete OutletCount = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
new JoinMetadata { Description = "Number of COntrolled Outlets", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
[JoinName("OutletName")]
public JoinDataComplete OutletName = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
[JoinName("OutletEnabled")]
public JoinDataComplete OutletEnabled = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Enabled", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerCycle")]
public JoinDataComplete OutletPowerCycle = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Cycle", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOn")]
public JoinDataComplete OutletPowerOn = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power On", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
[JoinName("OutletPowerOff")]
public JoinDataComplete OutletPowerOff = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
new JoinMetadata { Description = "Outlet Power Off", JoinCapabilities = eJoinCapabilities.ToFromSIMPL, JoinType = eJoinType.Digital });
/// <summary>
/// Constructor to use when instantiating this Join Map without inheriting from it
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
public PduJoinMapBase(uint joinStart)
:base(joinStart, typeof(PduJoinMapBase))
{
}
/// <summary>
/// Constructor to use when extending this Join map
/// </summary>
/// <param name="joinStart">Join this join map will start at</param>
/// <param name="type">Type of the child join map</param>
public PduJoinMapBase(uint joinStart, Type type)
: base(joinStart, type)
{
}
}
}

View file

@ -1,4 +1,4 @@
using System; using System;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.Core.Bridges.JoinMaps namespace PepperDash.Essentials.Core.Bridges.JoinMaps
{ {
@ -1576,6 +1576,36 @@ namespace PepperDash.Essentials.Core.Bridges.JoinMaps
JoinType = eJoinType.Serial JoinType = eJoinType.Serial
}); });
[JoinName("AvailableLayoutsFb")]
public JoinDataComplete AvailableLayoutsFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "xSig of all available layouts",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectLayout")]
public JoinDataComplete SelectLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select Layout by string",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentParticipants")] [JoinName("CurrentParticipants")]
public JoinDataComplete CurrentParticipants = new JoinDataComplete( public JoinDataComplete CurrentParticipants = new JoinDataComplete(
new JoinData new JoinData
@ -3014,6 +3044,35 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
JoinType = eJoinType.Serial JoinType = eJoinType.Serial
}); });
[JoinName("AvailableLayoutsFb")]
public JoinDataComplete AvailableLayoutsFb = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "xSig of all available layouts",
JoinCapabilities = eJoinCapabilities.ToSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("SelectLayout")]
public JoinDataComplete SelectLayout = new JoinDataComplete(
new JoinData
{
JoinNumber = 142,
JoinSpan = 1
},
new JoinMetadata
{
Description = "Select Layout by string",
JoinCapabilities = eJoinCapabilities.FromSIMPL,
JoinType = eJoinType.Serial
});
[JoinName("CurrentParticipants")] [JoinName("CurrentParticipants")]
public JoinDataComplete CurrentParticipants = new JoinDataComplete( public JoinDataComplete CurrentParticipants = new JoinDataComplete(
new JoinData new JoinData

View file

@ -39,7 +39,10 @@ namespace PepperDash.Essentials.Core.Config
Name = dc.Name; Name = dc.Name;
Group = dc.Group; Group = dc.Group;
Type = dc.Type; Type = dc.Type;
Properties = JToken.FromObject(dc.Properties);
Properties = JToken.Parse(dc.Properties.ToString());
//Properties = JToken.FromObject(dc.Properties);
} }
public DeviceConfig() {} public DeviceConfig() {}

View file

@ -73,20 +73,26 @@ namespace PepperDash.Essentials.Core
{ {
//Debug.Console(1, this, " Does not require registration. Skipping"); //Debug.Console(1, this, " Does not require registration. Skipping");
if (Hardware.Registerable && !Hardware.Registered)
{
var response = Hardware.RegisterWithLogging(Key); var response = Hardware.RegisterWithLogging(Key);
if (response != eDeviceRegistrationUnRegistrationResponse.Success) if (response != eDeviceRegistrationUnRegistrationResponse.Success)
{ {
//Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response); //Debug.Console(0, this, "ERROR: Cannot register Crestron device: {0}", response);
return false; return false;
} }
}
IsRegistered.FireUpdate(); IsRegistered.FireUpdate();
} }
else else
{ {
AddPostActivationAction(() => AddPostActivationAction(() =>
{
if (Hardware.Registerable && !Hardware.Registered)
{ {
var response = Hardware.RegisterWithLogging(Key); var response = Hardware.RegisterWithLogging(Key);
}
IsRegistered.FireUpdate(); IsRegistered.FireUpdate();
}); });

View file

@ -14,6 +14,7 @@ namespace PepperDash.Essentials.Core
public static class DeviceManager public static class DeviceManager
{ {
public static event EventHandler<EventArgs> AllDevicesActivated; public static event EventHandler<EventArgs> AllDevicesActivated;
public static event EventHandler<EventArgs> AllDevicesRegistered;
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection(); private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true); private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
@ -57,6 +58,8 @@ namespace PepperDash.Essentials.Core
{ {
try try
{ {
OnAllDevicesRegistered();
DeviceCriticalSection.Enter(); DeviceCriticalSection.Enter();
AddDeviceEnabled = false; AddDeviceEnabled = false;
// PreActivate all devices // PreActivate all devices
@ -129,6 +132,15 @@ namespace PepperDash.Essentials.Core
} }
} }
private static void OnAllDevicesRegistered()
{
var handler = AllDevicesRegistered;
if (handler != null)
{
handler(null, new EventArgs());
}
}
/// <summary> /// <summary>
/// Calls activate on all Device class items /// Calls activate on all Device class items
/// </summary> /// </summary>

View file

@ -7,7 +7,7 @@ using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
/// <summary> /// <summary>
/// Defines minimal volume control methods /// Defines minimal volume and mute control methods
/// </summary> /// </summary>
public interface IBasicVolumeControls public interface IBasicVolumeControls
{ {
@ -16,16 +16,52 @@ namespace PepperDash.Essentials.Core
void MuteToggle(); void MuteToggle();
} }
/// <summary>
/// Defines basic volume control methods
/// </summary>
public interface IHasVolumeControl
{
void VolumeUp(bool pressRelease);
void VolumeDown(bool pressRelease);
}
/// <summary>
/// Defines volume control methods and properties with feedback
/// </summary>
public interface IHasVolumeControlWithFeedback : IHasVolumeControl
{
void SetVolume(ushort level);
IntFeedback VolumeLevelFeedback { get; }
}
/// <summary>
/// Defines basic mute control methods
/// </summary>
public interface IHasMuteControl
{
void MuteToggle();
}
/// <summary>
/// Defines mute control methods and properties with feedback
/// </summary>
public interface IHasMuteControlWithFeedback : IHasMuteControl
{
BoolFeedback MuteFeedback { get; }
void MuteOn();
void MuteOff();
}
/// <summary> /// <summary>
/// Adds feedback and direct volume level set to IBasicVolumeControls /// Adds feedback and direct volume level set to IBasicVolumeControls
/// </summary> /// </summary>
public interface IBasicVolumeWithFeedback : IBasicVolumeControls public interface IBasicVolumeWithFeedback : IBasicVolumeControls
{ {
void SetVolume(ushort level); BoolFeedback MuteFeedback { get; }
void MuteOn(); void MuteOn();
void MuteOff(); void MuteOff();
void SetVolume(ushort level);
IntFeedback VolumeLevelFeedback { get; } IntFeedback VolumeLevelFeedback { get; }
BoolFeedback MuteFeedback { get; }
} }
/// <summary> /// <summary>

View file

@ -0,0 +1,35 @@
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash_Essentials_Core.Devices
{
/// <summary>
/// Interface for any device that is able to control it'spower and has a configurable reboot time
/// </summary>
public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
{
/// <summary>
/// Delay between power off and power on for reboot
/// </summary>
int PowerCycleTimeMs { get;}
/// <summary>
/// Reboot outlet
/// </summary>
void PowerCycle();
}
/// <summary>
/// Interface for any device that contains a collection of IHasPowerReboot Devices
/// </summary>
public interface IHasControlledPowerOutlets : IKeyName
{
/// <summary>
/// Collection of IPduOutlets
/// </summary>
ReadOnlyDictionary<int, IHasPowerCycle> PduOutlets { get; }
}
}

View file

@ -59,7 +59,7 @@ namespace PepperDash.Essentials.Core.Devices
/// <summary> /// <summary>
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc) /// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
/// </summary> /// </summary>
/// <param name="Config"></param> /// <param name="config"></param>
protected virtual void CustomSetConfig(DeviceConfig config) protected virtual void CustomSetConfig(DeviceConfig config)
{ {
ConfigWriter.UpdateDeviceConfig(config); ConfigWriter.UpdateDeviceConfig(config);

View file

@ -0,0 +1,278 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using PepperDash.Core;
using Crestron.SimplSharpPro.CrestronThread;
namespace PepperDash.Essentials.Core
{
public static class FileIO
{
static CCriticalSection fileLock = new CCriticalSection();
public delegate void GotFileEventHandler(object sender, FileEventArgs e);
public static event GotFileEventHandler GotFileEvent;
/// <summary>
/// Get the full file info from a path/filename, can include wildcards.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static FileInfo[] GetFiles(string fileName)
{
DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fileName));
var files = dirInfo.GetFiles(Path.GetFileName(fileName));
Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fileName);
if (files.Count() > 0)
{
return files;
}
else
{
return null;
}
}
public static FileInfo GetFile(string fileName)
{
DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(fileName));
var files = dirInfo.GetFiles(Path.GetFileName(fileName));
Debug.Console(0, "FileIO found: {0}, {1}", files.Count(), fileName);
if (files.Count() > 0)
{
return files.FirstOrDefault();
}
else
{
return null;
}
}
/// <summary>
/// Get the data from string path/filename
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(string fileName)
{
try
{
return ReadDataFromFile(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
}
/// <summary>
/// Get the data with fileInfo object
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(FileInfo file)
{
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
return r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} does not exsist", file.FullName);
return "";
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
return "";
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
public static void ReadDataFromFileASync(string fileName)
{
try
{
ReadDataFromFileASync(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
public static void ReadDataFromFileASync(FileInfo file)
{
try
{
CrestronInvoke.BeginInvoke(o => _ReadDataFromFileASync(file));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
private static void _ReadDataFromFileASync(FileInfo file)
{
string data;
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
data = r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} Does not exsist", file.FullName);
data = "";
}
GotFileEvent.Invoke(null, new FileEventArgs(data));
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
data = "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
public static void WriteDataToFile(string data, string filePath)
{
Thread _WriteFileThread;
_WriteFileThread = new Thread((O) => _WriteFileMethod(data, filePath), null, Thread.eThreadStartOptions.CreateSuspended);
_WriteFileThread.Priority = Thread.eThreadPriority.LowestPriority;
_WriteFileThread.Start();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WriteFile Thread");
}
static object _WriteFileMethod(string data, string filePath)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(data);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
return null;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static bool FileIoUnitTest()
{
var testData = "Testing FileIO";
FileIO.WriteDataToFile(testData, "\\user\\FileIOTest.pdt");
var file = FileIO.GetFile("\\user\\*FileIOTest*");
var readData = FileIO.ReadDataFromFile(file);
Debug.Console(0, "Returned {0}", readData);
File.Delete(file.FullName);
if (testData == readData)
{
return true;
}
else
{
return false;
}
}
}
public class FileEventArgs
{
public FileEventArgs(string data) { Data = data; }
public string Data { get; private set; } // readonly
}
}

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharp.CrestronDataStore; using Crestron.SimplSharp.CrestronDataStore;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.License; using PepperDash.Essentials.License;
@ -39,7 +40,14 @@ namespace PepperDash.Essentials.Core
{ {
get get
{ {
return ControlSystem.ControllerPrompt.ToLower().IndexOf("dmps") > -1; if(ControlSystem.SystemControl != null)
{
if(ControlSystem.SystemControl.SystemControlType > 0)
{
return true;
}
}
return false;
} }
} }
@ -50,7 +58,39 @@ namespace PepperDash.Essentials.Core
{ {
get get
{ {
return ControlSystemIsDmpsType && ControlSystem.ControllerPrompt.ToLower().IndexOf("4k") > -1; if(ControlSystem.SystemControl != null)
{
if(ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K150CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K200CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K300CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
{
return true;
}
}
return false;
}
}
/// <summary>
/// True when the processor type is a DMPS 4K 200/300/250/350 variant
/// </summary>
public static bool ControlSystemIsDmps4k3xxType
{
get
{
if(ControlSystem.SystemControl != null)
{
if(ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K200CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K300CSystemControl ||
ControlSystem.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
{
return true;
}
}
return false;
} }
} }

View file

@ -94,8 +94,6 @@ namespace PepperDash.Essentials.Core.Lighting
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap) protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
{ {
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString()); Debug.Console(0, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
@ -135,7 +133,6 @@ namespace PepperDash.Essentials.Core.Lighting
return joinMap; return joinMap;
} }
} }
public class LightingScene public class LightingScene

View file

@ -123,6 +123,7 @@
<Compile Include="Bridges\IBridge.cs" /> <Compile Include="Bridges\IBridge.cs" />
<Compile Include="Bridges\JoinMaps\AirMediaControllerJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\AirMediaControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\AppleTvJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\AppleTvJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\PduJoinMapBase.cs" />
<Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\C2nRthsControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\CameraControllerJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\CameraControllerJoinMap.cs" />
<Compile Include="Bridges\JoinMaps\CenOdtOccupancySensorBaseJoinMap.cs" /> <Compile Include="Bridges\JoinMaps\CenOdtOccupancySensorBaseJoinMap.cs" />
@ -204,6 +205,7 @@
<Compile Include="Devices\IReconfigurableDevice.cs" /> <Compile Include="Devices\IReconfigurableDevice.cs" />
<Compile Include="Devices\PC\InRoomPc.cs" /> <Compile Include="Devices\PC\InRoomPc.cs" />
<Compile Include="Devices\PC\Laptop.cs" /> <Compile Include="Devices\PC\Laptop.cs" />
<Compile Include="Devices\PduInterfaces.cs" />
<Compile Include="Devices\ReconfigurableDevice.cs" /> <Compile Include="Devices\ReconfigurableDevice.cs" />
<Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" /> <Compile Include="Devices\VolumeDeviceChangeEventArgs.cs" />
<Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" /> <Compile Include="DeviceTypeInterfaces\IPasswordPrompt.cs" />
@ -225,6 +227,7 @@
<Compile Include="Feedbacks\IntFeedback.cs" /> <Compile Include="Feedbacks\IntFeedback.cs" />
<Compile Include="Feedbacks\SerialFeedback.cs" /> <Compile Include="Feedbacks\SerialFeedback.cs" />
<Compile Include="Feedbacks\StringFeedback.cs" /> <Compile Include="Feedbacks\StringFeedback.cs" />
<Compile Include="File\FileIO.cs" />
<Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" /> <Compile Include="Fusion\EssentialsHuddleSpaceFusionSystemControllerBase.cs" />
<Compile Include="Fusion\FusionCustomPropertiesBridge.cs" /> <Compile Include="Fusion\FusionCustomPropertiesBridge.cs" />
<Compile Include="Fusion\FusionEventHandlers.cs" /> <Compile Include="Fusion\FusionEventHandlers.cs" />
@ -336,7 +339,9 @@
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" /> <Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
<Compile Include="Routing\RoutingPortNames.cs" /> <Compile Include="Routing\RoutingPortNames.cs" />
<Compile Include="Routing\TieLineConfig.cs" /> <Compile Include="Routing\TieLineConfig.cs" />
<Compile Include="Secrets\CrestronSecretsProvider.cs" /> <Compile Include="Secrets\CrestronGlobalSecretsProvider.cs" />
<Compile Include="Secrets\CrestronLocalSecretsProvider.cs" />
<Compile Include="Secrets\CrestronSecret.cs" />
<Compile Include="Secrets\Interfaces.cs" /> <Compile Include="Secrets\Interfaces.cs" />
<Compile Include="Secrets\SecretsManager.cs" /> <Compile Include="Secrets\SecretsManager.cs" />
<Compile Include="Secrets\SecretsPropertiesConfig.cs" /> <Compile Include="Secrets\SecretsPropertiesConfig.cs" />

View file

@ -0,0 +1,102 @@
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
public class CrestronGlobalSecretsProvider : ISecretProvider
{
public string Key { get; set; }
//Added for reference
public string Description { get; private set; }
public CrestronGlobalSecretsProvider(string key)
{
Key = key;
Description = String.Format("Default secret provider serving all local applications");
}
static CrestronGlobalSecretsProvider()
{
//Added for future encrypted reference
var secureSupported = CrestronSecureStorage.Supported;
CrestronDataStoreStatic.InitCrestronDataStore();
if (secureSupported)
{
//doThingsFuture
}
}
/// <summary>
/// Set secret for item in the CrestronSecretsProvider
/// </summary>
/// <param name="key">Secret Key</param>
/// <param name="value">Secret Value</param>
public bool SetSecret(string key, object value)
{
var secret = value as string;
CrestronDataStore.CDS_ERROR returnCode;
if (String.IsNullOrEmpty(secret))
{
returnCode = CrestronDataStoreStatic.clearGlobal(key);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret);
return true;
}
}
else
{
returnCode = CrestronDataStoreStatic.SetGlobalStringValue(key, secret);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully set secret \"{0}\"", secret);
return true;
}
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.ToString());
return false;
}
/// <summary>
/// Retrieve secret for item in the CrestronSecretsProvider
/// </summary>
/// <param name="key">Secret Key</param>
/// <returns>ISecret Object containing key, provider, and value</returns>
public ISecret GetSecret(string key)
{
string mySecret;
var getErrorCode = CrestronDataStoreStatic.GetGlobalStringValue(key, out mySecret);
switch (getErrorCode)
{
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key);
return new CrestronSecret(key, mySecret, this);
default:
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
Key, key, getErrorCode.ToString());
return null;
}
}
/// <summary>
/// Determine if a secret is present within the provider without retrieving it
/// </summary>
/// <param name="key">Secret Key</param>
/// <returns>bool if present</returns>
public bool TestSecret(string key)
{
string mySecret;
return CrestronDataStoreStatic.GetGlobalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS;
}
}
}

View file

@ -2,27 +2,31 @@
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronDataStore; using Crestron.SimplSharp.CrestronDataStore;
using PepperDash.Core; using PepperDash.Core;
using Crestron.SimplSharpPro;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
public class CrestronSecretsProvider : ISecretProvider public class CrestronLocalSecretsProvider : ISecretProvider
{ {
public string Key { get; set; } public string Key { get; set; }
//Added for reference //Added for reference
private static readonly bool SecureSupported; public string Description { get; private set; }
public CrestronSecretsProvider(string key)
public CrestronLocalSecretsProvider(string key)
{ {
Key = key; Key = key;
Description = String.Format("Default secret provider serving Essentials Application {0}", InitialParametersClass.ApplicationNumber);
} }
static CrestronSecretsProvider() static CrestronLocalSecretsProvider()
{ {
//Added for future encrypted reference //Added for future encrypted reference
SecureSupported = CrestronSecureStorage.Supported; var secureSupported = CrestronSecureStorage.Supported;
CrestronDataStoreStatic.InitCrestronDataStore(); CrestronDataStoreStatic.InitCrestronDataStore();
if (SecureSupported) if (secureSupported)
{ {
//doThingsFuture //doThingsFuture
} }
@ -36,23 +40,32 @@ namespace PepperDash.Essentials.Core
public bool SetSecret(string key, object value) public bool SetSecret(string key, object value)
{ {
var secret = value as string; var secret = value as string;
CrestronDataStore.CDS_ERROR returnCode;
if (String.IsNullOrEmpty(secret)) if (String.IsNullOrEmpty(secret))
{ {
Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key); returnCode = CrestronDataStoreStatic.clearLocal(key);
return false; if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
}
var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
switch (setErrorCode)
{ {
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret);
Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key);
return true; return true;
default:
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
return false;
} }
} }
else
{
returnCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
Debug.Console(0, this, "Successfully set secret \"{0}\"", secret);
return true;
}
}
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.ToString());
return false;
}
/// <summary> /// <summary>
/// Retrieve secret for item in the CrestronSecretsProvider /// Retrieve secret for item in the CrestronSecretsProvider
/// </summary> /// </summary>
@ -74,24 +87,17 @@ namespace PepperDash.Essentials.Core
return null; return null;
} }
} }
}
/// <summary> /// <summary>
/// Special container class for CrestronSecret provider /// Determine if a secret is present within the provider without retrieving it
/// </summary> /// </summary>
public class CrestronSecret : ISecret /// <param name="key">Secret Key</param>
/// <returns>bool if present</returns>
public bool TestSecret(string key)
{ {
public ISecretProvider Provider { get; private set; } string mySecret;
public string Key { get; private set; } return CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS;
}
public object Value { get; private set; }
public CrestronSecret(string key, string value, ISecretProvider provider)
{
Key = key;
Value = value;
Provider = provider;
} }
}
} }

View file

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Special container class for CrestronSecret provider
/// </summary>
public class CrestronSecret : ISecret
{
public ISecretProvider Provider { get; private set; }
public string Key { get; private set; }
public object Value { get; private set; }
public CrestronSecret(string key, string value, ISecretProvider provider)
{
Key = key;
Value = value;
Provider = provider;
}
}
}

View file

@ -7,9 +7,32 @@ namespace PepperDash.Essentials.Core
/// </summary> /// </summary>
public interface ISecretProvider : IKeyed public interface ISecretProvider : IKeyed
{ {
/// <summary>
/// Set secret value for provider by key
/// </summary>
/// <param name="key">key of secret to set</param>
/// <param name="value">value to set secret to</param>
/// <returns></returns>
bool SetSecret(string key, object value); bool SetSecret(string key, object value);
/// <summary>
/// Return object containing secret from provider
/// </summary>
/// <param name="key">key of secret to retrieve</param>
/// <returns></returns>
ISecret GetSecret(string key); ISecret GetSecret(string key);
/// <summary>
/// Verifies presence of secret
/// </summary>
/// <param name="key">key of secret to chek</param>
/// <returns></returns>
bool TestSecret(string key);
/// <summary>
/// Description of the secrets provider
/// </summary>
string Description { get; }
} }
/// <summary> /// <summary>
@ -17,8 +40,19 @@ namespace PepperDash.Essentials.Core
/// </summary> /// </summary>
public interface ISecret public interface ISecret
{ {
/// <summary>
/// Instance of ISecretProvider that the secret belongs to
/// </summary>
ISecretProvider Provider { get; } ISecretProvider Provider { get; }
/// <summary>
/// Key of the secret in the provider
/// </summary>
string Key { get; } string Key { get; }
/// <summary>
/// Value of the secret
/// </summary>
object Value { get; } object Value { get; }
} }
} }

View file

@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using PepperDash.Core; using PepperDash.Core;
namespace PepperDash.Essentials.Core namespace PepperDash.Essentials.Core
{ {
public static class SecretsManager public static class SecretsManager
@ -16,18 +16,28 @@ namespace PepperDash.Essentials.Core
public static void Initialize() public static void Initialize()
{ {
AddSecretProvider("default", new CrestronSecretsProvider("default")); AddSecretProvider("default", new CrestronLocalSecretsProvider("default"));
AddSecretProvider("CrestronGlobalSecrets", new CrestronGlobalSecretsProvider("CrestronGlobalSecrets"));
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret", CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
"Adds secrets to secret provider", "Adds secret to secrets provider",
ConsoleAccessLevelEnum.AccessOperator); ConsoleAccessLevelEnum.AccessOperator);
CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret", CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret",
"Updates secrets in secret provider", "Updates secret in secrets provider",
ConsoleAccessLevelEnum.AccessAdministrator); ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret", CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
"Deletes secrets in secret provider", "Deletes secret from secrest provider",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(ListProviders, "secretproviderlist",
"Return list of all valid secrets providers",
ConsoleAccessLevelEnum.AccessAdministrator);
CrestronConsole.AddNewConsoleCommand(GetProviderInfo, "secretproviderinfo",
"Return data about secrets provider",
ConsoleAccessLevelEnum.AccessAdministrator); ConsoleAccessLevelEnum.AccessAdministrator);
} }
@ -54,6 +64,79 @@ namespace PepperDash.Essentials.Core
return secret; return secret;
} }
public static void GetProviderInfo(string cmd)
{
string response;
var args = cmd.Split(' ');
if (cmd.Length == 0 || (args.Length == 1 && args[0] == "?"))
{
response = "Returns data about secrets provider. Format 'secretproviderinfo <provider>'";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1)
{
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
response = "Invalid secrets provider key";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = String.Format("{0} : {1}", provider.Key, provider.Description);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
}
/// <summary>
/// Console Command that returns all valid secrets in the essentials program.
/// </summary>
/// <param name="cmd"></param>
public static void ListProviders(string cmd)
{
var response = String.Empty;
var args = cmd.Split(' ');
if (cmd.Length == 0)
{
if (Secrets != null && Secrets.Count > 0)
{
response = Secrets.Aggregate(response,
(current, secretProvider) => current + (secretProvider.Key + "\n\r"));
}
else
{
response = "No Secrets Providers Available";
}
CrestronConsole.ConsoleCommandResponse(response);
return;
}
if (args.Length == 1 && args[0] == "?")
{
response = "Reports all valid and preset Secret providers";
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response = "Improper number of arguments";
CrestronConsole.ConsoleCommandResponse(response);
}
/// <summary> /// <summary>
/// Add secret provider to secrets dictionary /// Add secret provider to secrets dictionary
/// </summary> /// </summary>
@ -100,14 +183,14 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0) if (args.Length == 0)
{ {
//some Instructional Text //some Instructional Text
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>"; response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
if (args.Length == 1 && args[0] == "?") if (args.Length == 1 && args[0] == "?")
{ {
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>"; response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
@ -134,23 +217,7 @@ namespace PepperDash.Essentials.Core
var key = args[1]; var key = args[1];
var secret = args[2]; var secret = args[2];
if (provider.GetSecret(key) == null) CrestronConsole.ConsoleCommandResponse(SetSecret(provider, key, secret));
{
response = provider.SetSecret(key, secret)
? String.Format(
"Secret successfully set for {0}:{1}",
provider.Key, key)
: String.Format(
"Unable to set secret for {0}:{1}",
provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
response =
String.Format(
"Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it");
CrestronConsole.ConsoleCommandResponse(response);
} }
private static void UpdateSecretProcess(string cmd) private static void UpdateSecretProcess(string cmd)
@ -161,7 +228,7 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0) if (args.Length == 0)
{ {
//some Instructional Text //some Instructional Text
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>"; response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
@ -169,7 +236,7 @@ namespace PepperDash.Essentials.Core
if (args.Length == 1 && args[0] == "?") if (args.Length == 1 && args[0] == "?")
{ {
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>"; response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>'";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
@ -198,23 +265,49 @@ namespace PepperDash.Essentials.Core
var key = args[1]; var key = args[1];
var secret = args[2]; var secret = args[2];
if (provider.GetSecret(key) != null) CrestronConsole.ConsoleCommandResponse(UpdateSecret(provider, key, secret));
}
private static string UpdateSecret(ISecretProvider provider, string key, string secret)
{ {
response = provider.SetSecret(key, secret) var secretPresent = provider.TestSecret(key);
Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key);
if (!secretPresent)
return
String.Format(
"Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to modify it");
var response = provider.SetSecret(key, secret)
? String.Format( ? String.Format(
"Secret successfully set for {0}:{1}", "Secret successfully set for {0}:{1}",
provider.Key, key) provider.Key, key)
: String.Format( : String.Format(
"Unable to set secret for {0}:{1}", "Unable to set secret for {0}:{1}",
provider.Key, key); provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response); return response;
return;
} }
response = private static string SetSecret(ISecretProvider provider, string key, string secret)
{
var secretPresent = provider.TestSecret(key);
Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key);
if (secretPresent)
return
String.Format( String.Format(
"Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to create a new secret"); "Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it");
CrestronConsole.ConsoleCommandResponse(response); var response = provider.SetSecret(key, secret)
? String.Format(
"Secret successfully set for {0}:{1}",
provider.Key, key)
: String.Format(
"Unable to set secret for {0}:{1}",
provider.Key, key);
return response;
} }
private static void DeleteSecretProcess(string cmd) private static void DeleteSecretProcess(string cmd)
@ -225,14 +318,14 @@ namespace PepperDash.Essentials.Core
if (args.Length == 0) if (args.Length == 0)
{ {
//some Instructional Text //some Instructional Text
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>"; response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>'";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }
if (args.Length == 1 && args[0] == "?") if (args.Length == 1 && args[0] == "?")
{ {
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>"; response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>'";
CrestronConsole.ConsoleCommandResponse(response); CrestronConsole.ConsoleCommandResponse(response);
return; return;
} }

View file

@ -144,7 +144,7 @@ namespace PepperDash.Essentials.Core
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum) public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
{ {
if (sigNum > UShortIncrement) return null; if (sigNum > UShortIncrement) return null;
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum))); return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetUShortOutputSigName(index, sigNum)));
} }
/// <summary> /// <summary>
@ -159,7 +159,7 @@ namespace PepperDash.Essentials.Core
public StringOutputSig GetStringOutputSig(uint index, uint sigNum) public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
{ {
if (sigNum > StringIncrement) return null; if (sigNum > StringIncrement) return null;
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum))); return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetStringOutputSigName(index, sigNum)));
} }
/// <summary> /// <summary>

View file

@ -1482,6 +1482,8 @@ namespace PepperDash.Essentials.DM
LinkChassisToApi(trilist, joinMap); LinkChassisToApi(trilist, joinMap);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
// Link up inputs & outputs // Link up inputs & outputs
for (uint i = 1; i <= Chassis.NumberOfOutputs; i++) for (uint i = 1; i <= Chassis.NumberOfOutputs; i++)
{ {

View file

@ -17,52 +17,89 @@ using PepperDash.Essentials.DM.Config;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
/// <summary> /// <summary>
/// Exposes the volume levels for Program, Aux1 or Aux2 outputs on a DMPS3 chassis /// Exposes the volume levels for Program, Aux1, Aux2, Codec1, Codec2, and Digital outputs on a DMPS3 chassis
/// </summary> /// </summary>
public class DmpsAudioOutputController : EssentialsBridgeableDevice public class DmpsAudioOutputController : EssentialsBridgeableDevice
{ {
Card.Dmps3OutputBase OutputCard;
public DmpsAudioOutput MasterVolumeLevel { get; private set; } public DmpsAudioOutput MasterVolumeLevel { get; private set; }
public DmpsAudioOutput SourceVolumeLevel { get; private set; } public DmpsAudioOutput SourceVolumeLevel { get; private set; }
public DmpsAudioOutput MicsMasterVolumeLevel { get; private set; } public DmpsAudioOutput MicsMasterVolumeLevel { get; private set; }
public DmpsAudioOutput Codec1VolumeLevel { get; private set; } public DmpsAudioOutput Codec1VolumeLevel { get; private set; }
public DmpsAudioOutput Codec2VolumeLevel { get; private set; } public DmpsAudioOutput Codec2VolumeLevel { get; private set; }
public DmpsAudioOutputController(string key, string name, DMOutput card, Card.Dmps3DmHdmiAudioOutput.Dmps3AudioOutputStream stream)
: base(key, name)
{
card.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
var output = new Dmps3AudioOutputWithMixerBase(stream);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
}
public DmpsAudioOutputController(string key, string name, DMOutput card, Card.Dmps3DmHdmiAudioOutput.Dmps3DmHdmiOutputStream stream)
: base(key, name)
{
card.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
var output = new Dmps3AudioOutputWithMixerBase(stream);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
}
public DmpsAudioOutputController(string key, string name, Card.Dmps3OutputBase card) public DmpsAudioOutputController(string key, string name, Card.Dmps3OutputBase card)
: base(key, name) : base(key, name)
{ {
OutputCard = card; card.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
OutputCard.BaseDevice.DMOutputChange += new DMOutputEventHandler(BaseDevice_DMOutputChange);
if (card is Card.Dmps3ProgramOutput) if (card is Card.Dmps3ProgramOutput)
{ {
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3ProgramOutput).OutputMixer); var programOutput = card as Card.Dmps3ProgramOutput;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); var output = new Dmps3AudioOutputWithMixerBase(card, programOutput.OutputMixer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(output, eDmpsLevelType.Master, programOutput.OutputEqualizer);
Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec1);
Codec2VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec2);
} }
else if (card is Card.Dmps3Aux1Output) else if (card is Card.Dmps3Aux1Output)
{ {
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux1Output).OutputMixer); var auxOutput = card as Card.Dmps3Aux1Output;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); var output = new Dmps3AudioOutputWithMixerBase(card, auxOutput.OutputMixer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(output, eDmpsLevelType.Master, auxOutput.OutputEqualizer);
Codec2VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec2); SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
Codec2VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec2);
} }
else if (card is Card.Dmps3Aux2Output) else if (card is Card.Dmps3Aux2Output)
{ {
MasterVolumeLevel = new DmpsAudioOutputWithMixer(card, eDmpsLevelType.Master, (card as Card.Dmps3Aux2Output).OutputMixer); var auxOutput = card as Card.Dmps3Aux2Output;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); var output = new Dmps3AudioOutputWithMixerBase(card, auxOutput.OutputMixer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); MasterVolumeLevel = new DmpsAudioOutputWithMixerAndEq(output, eDmpsLevelType.Master, auxOutput.OutputEqualizer);
Codec1VolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Codec1); SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
Codec1VolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Codec1);
} }
else //Digital Outputs else if (card is Card.Dmps3DigitalMixOutput)
{ {
MasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Master); var mixOutput = card as Card.Dmps3DigitalMixOutput;
SourceVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.Source); var output = new Dmps3AudioOutputWithMixerBase(card, mixOutput.OutputMixer);
MicsMasterVolumeLevel = new DmpsAudioOutput(card, eDmpsLevelType.MicsMaster); MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
}
else if (card is Card.Dmps3HdmiOutput)
{
var hdmiOutput = card as Card.Dmps3HdmiOutput;
var output = new Dmps3AudioOutputWithMixerBase(card, hdmiOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
}
else if (card is Card.Dmps3DmOutput)
{
var dmOutput = card as Card.Dmps3DmOutput;
var output = new Dmps3AudioOutputWithMixerBase(card, dmOutput.OutputMixer);
MasterVolumeLevel = new DmpsAudioOutputWithMixer(output, eDmpsLevelType.Master);
SourceVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.Source);
MicsMasterVolumeLevel = new DmpsAudioOutput(output, eDmpsLevelType.MicsMaster);
} }
} }
@ -185,6 +222,11 @@ namespace PepperDash.Essentials.DM
{ {
trilist.SetUShortSigAction(joinMap.MixerPresetRecall.JoinNumber, mixer.RecallPreset); trilist.SetUShortSigAction(joinMap.MixerPresetRecall.JoinNumber, mixer.RecallPreset);
} }
var eq = MasterVolumeLevel as DmpsAudioOutputWithMixerAndEq;
if (eq != null)
{
trilist.SetUShortSigAction(joinMap.MixerEqPresetRecall.JoinNumber, eq.RecallEqPreset);
}
} }
if (SourceVolumeLevel != null) if (SourceVolumeLevel != null)
@ -234,21 +276,37 @@ namespace PepperDash.Essentials.DM
} }
} }
public class DmpsAudioOutputWithMixer : DmpsAudioOutput public class DmpsAudioOutputWithMixerAndEq : DmpsAudioOutputWithMixer
{ {
CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo Mixer; private CrestronControlSystem.Dmps3OutputEqualizer Eq;
public DmpsAudioOutputWithMixerAndEq(Dmps3AudioOutputWithMixerBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputEqualizer eq)
public DmpsAudioOutputWithMixer(Card.Dmps3OutputBase output, eDmpsLevelType type, CrestronControlSystem.Dmps3OutputMixerWithMonoAndStereo mixer)
: base(output, type) : base(output, type)
{ {
Mixer = mixer; Eq = eq;
}
public void RecallEqPreset(ushort preset)
{
Eq.PresetNumber.UShortValue = preset;
Eq.RecallPreset();
}
}
public class DmpsAudioOutputWithMixer : DmpsAudioOutput
{
Dmps3AudioOutputWithMixerBase Output;
public DmpsAudioOutputWithMixer(Dmps3AudioOutputWithMixerBase output, eDmpsLevelType type)
: base(output, type)
{
Output = output;
GetVolumeMax(); GetVolumeMax();
GetVolumeMin(); GetVolumeMin();
} }
public void GetVolumeMin() public void GetVolumeMin()
{ {
MinLevel = (short)Mixer.MinVolumeFeedback.UShortValue; MinLevel = (short)Output.MinVolumeFeedback.UShortValue;
if (VolumeLevelScaledFeedback != null) if (VolumeLevelScaledFeedback != null)
{ {
VolumeLevelScaledFeedback.FireUpdate(); VolumeLevelScaledFeedback.FireUpdate();
@ -257,7 +315,7 @@ namespace PepperDash.Essentials.DM
public void GetVolumeMax() public void GetVolumeMax()
{ {
MaxLevel = (short)Mixer.MaxVolumeFeedback.UShortValue; MaxLevel = (short)Output.MaxVolumeFeedback.UShortValue;
if (VolumeLevelScaledFeedback != null) if (VolumeLevelScaledFeedback != null)
{ {
VolumeLevelScaledFeedback.FireUpdate(); VolumeLevelScaledFeedback.FireUpdate();
@ -266,23 +324,36 @@ namespace PepperDash.Essentials.DM
public void RecallPreset(ushort preset) public void RecallPreset(ushort preset)
{ {
Debug.Console(1, "DMPS Recalling Preset {0}", preset); Output.PresetNumber.UShortValue = preset;
Mixer.PresetNumber.UShortValue = preset; Output.RecallPreset();
Mixer.RecallPreset();
if (!Global.ControlSystemIsDmps4k3xxType)
{
//Recall startup volume for main volume level as DMPS3(non-4K) presets don't affect the main volume
RecallStartupVolume();
}
}
public void RecallStartupVolume()
{
ushort startupVol = Output.StartupVolumeFeedback.UShortValue;
//Reset startup vol due to bug on DMPS3 where getting the value from above method clears the startup volume
Output.StartupVolume.UShortValue = startupVol;
Debug.Console(1, "DMPS Recalling Startup Volume {0}", startupVol);
SetVolume(startupVol);
MuteOff();
} }
} }
public class DmpsAudioOutput : IBasicVolumeWithFeedback public class DmpsAudioOutput : IBasicVolumeWithFeedback
{ {
Card.Dmps3OutputBase Output; private UShortInputSig Level;
eDmpsLevelType Type;
UShortInputSig Level;
private bool EnableVolumeSend; private bool EnableVolumeSend;
private ushort VolumeLevelInput; private ushort VolumeLevelInput;
protected short MinLevel { get; set; } protected short MinLevel { get; set; }
protected short MaxLevel { get; set; } protected short MaxLevel { get; set; }
public eDmpsLevelType Type { get; private set; }
public BoolFeedback MuteFeedback { get; private set; } public BoolFeedback MuteFeedback { get; private set; }
public IntFeedback VolumeLevelFeedback { get; private set; } public IntFeedback VolumeLevelFeedback { get; private set; }
public IntFeedback VolumeLevelScaledFeedback { get; private set; } public IntFeedback VolumeLevelScaledFeedback { get; private set; }
@ -292,9 +363,8 @@ namespace PepperDash.Essentials.DM
Action<bool> VolumeUpAction; Action<bool> VolumeUpAction;
Action<bool> VolumeDownAction; Action<bool> VolumeDownAction;
public DmpsAudioOutput(Card.Dmps3OutputBase output, eDmpsLevelType type) public DmpsAudioOutput(Dmps3AudioOutputBase output, eDmpsLevelType type)
{ {
Output = output;
VolumeLevelInput = 0; VolumeLevelInput = 0;
EnableVolumeSend = false; EnableVolumeSend = false;
Type = type; Type = type;
@ -306,47 +376,46 @@ namespace PepperDash.Essentials.DM
case eDmpsLevelType.Master: case eDmpsLevelType.Master:
{ {
Level = output.MasterVolume; Level = output.MasterVolume;
MuteFeedback = new BoolFeedback(new Func<bool>(() => output.MasterMuteOnFeedBack.BoolValue));
MuteFeedback = new BoolFeedback(new Func<bool>(() => Output.MasterMuteOnFeedBack.BoolValue)); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => output.MasterVolumeFeedBack.UShortValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => Output.MasterVolumeFeedBack.UShortValue)); MuteOnAction = new Action(output.MasterMuteOn);
MuteOnAction = new Action(Output.MasterMuteOn); MuteOffAction = new Action(output.MasterMuteOff);
MuteOffAction = new Action(Output.MasterMuteOff); VolumeUpAction = new Action<bool>((b) => output.MasterVolumeUp.BoolValue = b);
VolumeUpAction = new Action<bool>((b) => Output.MasterVolumeUp.BoolValue = b); VolumeDownAction = new Action<bool>((b) => output.MasterVolumeDown.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => Output.MasterVolumeDown.BoolValue = b);
break; break;
} }
case eDmpsLevelType.MicsMaster: case eDmpsLevelType.MicsMaster:
{ {
Level = output.MicMasterLevel; if (output.Card is Card.Dmps3OutputBase)
{
MuteFeedback = new BoolFeedback(new Func<bool>(() => Output.MicMasterMuteOnFeedBack.BoolValue)); var micOutput = output.Card as Card.Dmps3OutputBase;
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => Output.MicMasterLevelFeedBack.UShortValue)); Level = micOutput.MicMasterLevel;
MuteOnAction = new Action(Output.MicMasterMuteOn); MuteFeedback = new BoolFeedback(new Func<bool>(() => micOutput.MicMasterMuteOnFeedBack.BoolValue));
MuteOffAction = new Action(Output.MicMasterMuteOff); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => micOutput.MicMasterLevelFeedBack.UShortValue));
VolumeUpAction = new Action<bool>((b) => Output.MicMasterLevelUp.BoolValue = b); MuteOnAction = new Action(micOutput.MicMasterMuteOn);
VolumeDownAction = new Action<bool>((b) => Output.MicMasterLevelDown.BoolValue = b); MuteOffAction = new Action(micOutput.MicMasterMuteOff);
VolumeUpAction = new Action<bool>((b) => micOutput.MicMasterLevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => micOutput.MicMasterLevelDown.BoolValue = b);
}
break; break;
} }
case eDmpsLevelType.Source: case eDmpsLevelType.Source:
{ {
Level = output.SourceLevel; Level = output.SourceLevel;
MuteFeedback = new BoolFeedback(new Func<bool>(() => output.SourceMuteOnFeedBack.BoolValue));
MuteFeedback = new BoolFeedback(new Func<bool>(() => Output.SourceMuteOnFeedBack.BoolValue)); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => output.SourceLevelFeedBack.UShortValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => Output.SourceLevelFeedBack.UShortValue)); MuteOnAction = new Action(output.SourceMuteOn);
MuteOnAction = new Action(Output.SourceMuteOn); MuteOffAction = new Action(output.SourceMuteOff);
MuteOffAction = new Action(Output.SourceMuteOff); VolumeUpAction = new Action<bool>((b) => output.SourceLevelUp.BoolValue = b);
VolumeUpAction = new Action<bool>((b) => Output.SourceLevelUp.BoolValue = b); VolumeDownAction = new Action<bool>((b) => output.SourceLevelDown.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => Output.SourceLevelDown.BoolValue = b);
break; break;
} }
case eDmpsLevelType.Codec1: case eDmpsLevelType.Codec1:
{ {
var programOutput = output as Card.Dmps3ProgramOutput; if (output.Card is Card.Dmps3ProgramOutput)
if (programOutput != null)
{ {
var programOutput = output.Card as Card.Dmps3ProgramOutput;
Level = programOutput.Codec1Level; Level = programOutput.Codec1Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => programOutput.CodecMute1OnFeedback.BoolValue)); MuteFeedback = new BoolFeedback(new Func<bool>(() => programOutput.CodecMute1OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => programOutput.Codec1LevelFeedback.UShortValue)); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => programOutput.Codec1LevelFeedback.UShortValue));
MuteOnAction = new Action(programOutput.Codec1MuteOn); MuteOnAction = new Action(programOutput.Codec1MuteOn);
@ -354,12 +423,10 @@ namespace PepperDash.Essentials.DM
VolumeUpAction = new Action<bool>((b) => programOutput.Codec1LevelUp.BoolValue = b); VolumeUpAction = new Action<bool>((b) => programOutput.Codec1LevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => programOutput.Codec1LevelDown.BoolValue = b); VolumeDownAction = new Action<bool>((b) => programOutput.Codec1LevelDown.BoolValue = b);
} }
else else if (output.Card is Card.Dmps3Aux2Output)
{ {
var auxOutput = output as Card.Dmps3Aux2Output; var auxOutput = output.Card as Card.Dmps3Aux2Output;
Level = auxOutput.Codec1Level; Level = auxOutput.Codec1Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => auxOutput.CodecMute1OnFeedback.BoolValue)); MuteFeedback = new BoolFeedback(new Func<bool>(() => auxOutput.CodecMute1OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => auxOutput.Codec1LevelFeedback.UShortValue)); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => auxOutput.Codec1LevelFeedback.UShortValue));
MuteOnAction = new Action(auxOutput.Codec1MuteOn); MuteOnAction = new Action(auxOutput.Codec1MuteOn);
@ -371,12 +438,10 @@ namespace PepperDash.Essentials.DM
} }
case eDmpsLevelType.Codec2: case eDmpsLevelType.Codec2:
{ {
var programOutput = output as Card.Dmps3ProgramOutput; if (output.Card is Card.Dmps3ProgramOutput)
if (programOutput != null)
{ {
var programOutput = output.Card as Card.Dmps3ProgramOutput;
Level = programOutput.Codec2Level; Level = programOutput.Codec2Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => programOutput.CodecMute1OnFeedback.BoolValue)); MuteFeedback = new BoolFeedback(new Func<bool>(() => programOutput.CodecMute1OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => programOutput.Codec2LevelFeedback.UShortValue)); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => programOutput.Codec2LevelFeedback.UShortValue));
MuteOnAction = new Action(programOutput.Codec2MuteOn); MuteOnAction = new Action(programOutput.Codec2MuteOn);
@ -384,12 +449,11 @@ namespace PepperDash.Essentials.DM
VolumeUpAction = new Action<bool>((b) => programOutput.Codec2LevelUp.BoolValue = b); VolumeUpAction = new Action<bool>((b) => programOutput.Codec2LevelUp.BoolValue = b);
VolumeDownAction = new Action<bool>((b) => programOutput.Codec2LevelDown.BoolValue = b); VolumeDownAction = new Action<bool>((b) => programOutput.Codec2LevelDown.BoolValue = b);
} }
else else if (output.Card is Card.Dmps3Aux1Output)
{ {
var auxOutput = output as Card.Dmps3Aux1Output; var auxOutput = output.Card as Card.Dmps3Aux1Output;
Level = auxOutput.Codec2Level; Level = auxOutput.Codec2Level;
MuteFeedback = new BoolFeedback(new Func<bool>(() => auxOutput.CodecMute2OnFeedback.BoolValue)); MuteFeedback = new BoolFeedback(new Func<bool>(() => auxOutput.CodecMute2OnFeedback.BoolValue));
VolumeLevelFeedback = new IntFeedback(new Func<int>(() => auxOutput.Codec2LevelFeedback.UShortValue)); VolumeLevelFeedback = new IntFeedback(new Func<int>(() => auxOutput.Codec2LevelFeedback.UShortValue));
MuteOnAction = new Action(auxOutput.Codec2MuteOn); MuteOnAction = new Action(auxOutput.Codec2MuteOn);
@ -410,20 +474,27 @@ namespace PepperDash.Essentials.DM
public void SetVolumeScaled(ushort level) public void SetVolumeScaled(ushort level)
{ {
Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} level:{1} min:{2} max:{3}", Output.Name, level.ToString(), MinLevel.ToString(), MaxLevel.ToString()); if (ushort.MaxValue + MinLevel != 0)
{
VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel); VolumeLevelInput = (ushort)(level * (MaxLevel - MinLevel) / ushort.MaxValue + MinLevel);
if (EnableVolumeSend == true) if (EnableVolumeSend == true)
{ {
Level.UShortValue = VolumeLevelInput; Level.UShortValue = VolumeLevelInput;
} }
} }
}
public ushort ScaleVolumeFeedback(ushort level) public ushort ScaleVolumeFeedback(ushort level)
{ {
short signedLevel = (short)level; short signedLevel = (short)level;
Debug.Console(2, Debug.ErrorLogLevel.None, "Scaling DMPS volume:{0} feedback:{1} min:{2} max:{3}", Output.Name, signedLevel.ToString(), MinLevel.ToString(), MaxLevel.ToString());
if (MaxLevel - MinLevel != 0)
{
return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel)); return (ushort)((signedLevel - MinLevel) * ushort.MaxValue / (MaxLevel - MinLevel));
} }
else
return (ushort)MinLevel;
}
public void SendScaledVolume(bool pressRelease) public void SendScaledVolume(bool pressRelease)
{ {
@ -476,6 +547,150 @@ namespace PepperDash.Essentials.DM
#endregion #endregion
} }
public class Dmps3AudioOutputWithMixerBase : Dmps3AudioOutputBase
{
public UShortOutputSig MinVolumeFeedback { get; private set; }
public UShortOutputSig MaxVolumeFeedback { get; private set; }
public UShortInputSig StartupVolume { get; private set; }
public UShortOutputSig StartupVolumeFeedback { get; private set; }
public UShortInputSig PresetNumber { get; private set; }
public Action RecallPreset { get; private set; }
public Dmps3AudioOutputWithMixerBase(Card.Dmps3OutputBase card, CrestronControlSystem.Dmps3OutputMixer mixer)
: base(card)
{
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = mixer.PresetNumber;
RecallPreset = new Action(mixer.RecallPreset);
}
public Dmps3AudioOutputWithMixerBase(Card.Dmps3OutputBase card, CrestronControlSystem.Dmps3AttachableOutputMixer mixer)
: base(card)
{
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = mixer.PresetNumber;
RecallPreset = new Action(mixer.RecallPreset);
}
public Dmps3AudioOutputWithMixerBase(Card.Dmps3DmHdmiAudioOutput.Dmps3AudioOutputStream stream)
: base(stream)
{
var mixer = stream.OutputMixer;
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = stream.PresetNumber;
RecallPreset = new Action(stream.RecallPreset);
}
public Dmps3AudioOutputWithMixerBase(Card.Dmps3DmHdmiAudioOutput.Dmps3DmHdmiOutputStream stream)
: base(stream)
{
var mixer = stream.OutputMixer;
MinVolumeFeedback = mixer.MinVolumeFeedback;
MaxVolumeFeedback = mixer.MaxVolumeFeedback;
StartupVolume = mixer.StartupVolume;
StartupVolumeFeedback = mixer.StartupVolumeFeedback;
PresetNumber = stream.PresetNumber;
RecallPreset = new Action(stream.RecallPreset);
}
}
public class Dmps3AudioOutputBase
{
public DMOutput Card { get; private set; }
public BoolOutputSig MasterMuteOffFeedBack { get; private set; }
public BoolOutputSig MasterMuteOnFeedBack { get; private set; }
public UShortInputSig MasterVolume { get; private set; }
public UShortOutputSig MasterVolumeFeedBack { get; private set; }
public BoolInputSig MasterVolumeUp { get; private set; }
public BoolInputSig MasterVolumeDown { get; private set; }
public BoolOutputSig SourceMuteOffFeedBack { get; private set; }
public BoolOutputSig SourceMuteOnFeedBack { get; private set; }
public UShortInputSig SourceLevel { get; private set; }
public UShortOutputSig SourceLevelFeedBack { get; private set; }
public BoolInputSig SourceLevelUp { get; private set; }
public BoolInputSig SourceLevelDown { get; private set; }
public Action MasterMuteOff { get; private set; }
public Action MasterMuteOn { get; private set; }
public Action SourceMuteOff { get; private set; }
public Action SourceMuteOn { get; private set; }
public Dmps3AudioOutputBase(Card.Dmps3OutputBase card)
{
Card = card;
MasterMuteOffFeedBack = card.MasterMuteOffFeedBack;
MasterMuteOnFeedBack = card.MasterMuteOnFeedBack;
MasterVolume = card.MasterVolume;
MasterVolumeFeedBack = card.MasterVolumeFeedBack;
MasterVolumeUp = card.MasterVolumeUp;
MasterVolumeDown = card.MasterVolumeDown;
SourceMuteOffFeedBack = card.SourceMuteOffFeedBack;
SourceMuteOnFeedBack = card.SourceMuteOnFeedBack;
SourceLevel = card.SourceLevel;
SourceLevelFeedBack = card.SourceLevelFeedBack;
SourceLevelUp = card.SourceLevelUp;
SourceLevelDown = card.SourceLevelDown;
MasterMuteOff = new Action(card.MasterMuteOff);
MasterMuteOn = new Action(card.MasterMuteOn);
SourceMuteOff = new Action(card.SourceMuteOff);
SourceMuteOn = new Action(card.SourceMuteOn);
}
public Dmps3AudioOutputBase(Card.Dmps3DmHdmiAudioOutput.Dmps3AudioOutputStream stream)
{
MasterMuteOffFeedBack = stream.MasterMuteOffFeedBack;
MasterMuteOnFeedBack = stream.MasterMuteOnFeedBack;
MasterVolume = stream.MasterVolume;
MasterVolumeFeedBack = stream.MasterVolumeFeedBack;
MasterVolumeUp = stream.MasterVolumeUp;
MasterVolumeDown = stream.MasterVolumeDown;
SourceMuteOffFeedBack = stream.SourceMuteOffFeedBack;
SourceMuteOnFeedBack = stream.SourceMuteOnFeedBack;
SourceLevel = stream.SourceLevel;
SourceLevelFeedBack = stream.SourceLevelFeedBack;
SourceLevelUp = stream.SourceLevelUp;
SourceLevelDown = stream.SourceLevelDown;
MasterMuteOff = new Action(stream.MasterMuteOff);
MasterMuteOn = new Action(stream.MasterMuteOn);
SourceMuteOff = new Action(stream.SourceMuteOff);
SourceMuteOn = new Action(stream.SourceMuteOn);
}
public Dmps3AudioOutputBase(Card.Dmps3DmHdmiAudioOutput.Dmps3DmHdmiOutputStream stream)
{
MasterMuteOffFeedBack = stream.MasterMuteOffFeedBack;
MasterMuteOnFeedBack = stream.MasterMuteOnFeedBack;
MasterVolume = stream.MasterVolume;
MasterVolumeFeedBack = stream.MasterVolumeFeedBack;
MasterVolumeUp = stream.MasterVolumeUp;
MasterVolumeDown = stream.MasterVolumeDown;
SourceMuteOffFeedBack = stream.SourceMuteOffFeedBack;
SourceMuteOnFeedBack = stream.SourceMuteOnFeedBack;
SourceLevel = stream.SourceLevel;
SourceLevelFeedBack = stream.SourceLevelFeedBack;
SourceLevelUp = stream.SourceLevelUp;
SourceLevelDown = stream.SourceLevelDown;
MasterMuteOff = new Action(stream.MasterMuteOff);
MasterMuteOn = new Action(stream.MasterMuteOn);
SourceMuteOff = new Action(stream.SourceMuteOff);
SourceMuteOn = new Action(stream.SourceMuteOn);
}
}
public enum eDmpsLevelType public enum eDmpsLevelType
{ {
Master, Master,

View file

@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Cards;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.DM
{
/// <summary>
///
/// </summary>
public class DmpsDigitalOutputController : Device, IRoutingNumeric, IHasFeedback
{
public Card.Dmps3OutputBase OutputCard { get; protected set; }
public RoutingInputPort None { get; protected set; }
public RoutingInputPort DigitalMix1 { get; protected set; }
public RoutingInputPort DigitalMix2 { get; protected set; }
public RoutingInputPort AudioFollowsVideo { get; protected set; }
public RoutingOutputPort DigitalAudioOut { get; protected set; }
public IntFeedback AudioSourceNumericFeedback { get; protected set; }
/// <summary>
/// Returns a list containing the Outputs that we want to expose.
/// </summary>
public FeedbackCollection<Feedback> Feedbacks { get; private set; }
public virtual RoutingPortCollection<RoutingInputPort> InputPorts
{
get
{
return new RoutingPortCollection<RoutingInputPort>
{
None,
DigitalMix1,
DigitalMix2,
AudioFollowsVideo
};
}
}
public RoutingPortCollection<RoutingOutputPort> OutputPorts
{
get
{
return new RoutingPortCollection<RoutingOutputPort> { DigitalAudioOut };
}
}
public DmpsDigitalOutputController(string key, string name, Card.Dmps3OutputBase outputCard)
: base(key, name)
{
Feedbacks = new FeedbackCollection<Feedback>();
OutputCard = outputCard;
if (outputCard is Card.Dmps3DmOutputBackend)
{
AudioSourceNumericFeedback = new IntFeedback(() =>
{
return (int)(outputCard as Card.Dmps3DmOutputBackend).AudioOutSourceDeviceFeedback;
});
DigitalAudioOut = new RoutingOutputPort(DmPortName.DmOut + OutputCard.Number, eRoutingSignalType.Audio, eRoutingPortConnectionType.DmCat, null, this);
}
else if (outputCard is Card.Dmps3HdmiOutputBackend)
{
AudioSourceNumericFeedback = new IntFeedback(() =>
{
return (int)(outputCard as Card.Dmps3HdmiOutputBackend).AudioOutSourceDeviceFeedback;
});
DigitalAudioOut = new RoutingOutputPort(DmPortName.HdmiOut + OutputCard.Number, eRoutingSignalType.Audio, eRoutingPortConnectionType.Hdmi, null, this);
}
else
{
return;
}
None = new RoutingInputPort("None", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.NoRoute, this);
DigitalMix1 = new RoutingInputPort("DigitalMix1", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.DigitalMixer1, this);
DigitalMix2 = new RoutingInputPort("DigitalMix2", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.DigitalMixer2, this);
AudioFollowsVideo = new RoutingInputPort("AudioFollowsVideo", eRoutingSignalType.Audio, eRoutingPortConnectionType.DigitalAudio,
eDmps34KAudioOutSourceDevice.AudioFollowsVideo, this);
AddToFeedbackList(AudioSourceNumericFeedback);
}
/// <summary>
/// Adds feedback(s) to the list
/// </summary>
/// <param name="newFbs"></param>
public void AddToFeedbackList(params Feedback[] newFbs)
{
foreach (var f in newFbs)
{
if (f != null)
{
if (!Feedbacks.Contains(f))
{
Feedbacks.Add(f);
}
}
}
}
public virtual void ExecuteNumericSwitch(ushort input, ushort output, eRoutingSignalType type)
{
Debug.Console(2, this, "Executing Numeric Switch to input {0}.", input);
switch (input)
{
case 0:
{
ExecuteSwitch(None.Selector, null, type);
break;
}
case 1:
{
ExecuteSwitch(DigitalMix1.Selector, null, type);
break;
}
case 2:
{
ExecuteSwitch(DigitalMix2.Selector, null, type);
break;
}
case 3:
{
ExecuteSwitch(AudioFollowsVideo.Selector, null, type);
break;
}
}
}
#region IRouting Members
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType signalType)
{
if ((signalType | eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
if (OutputCard is Card.Dmps3DmOutputBackend)
{
(OutputCard as Card.Dmps3DmOutputBackend).AudioOutSourceDevice = (eDmps34KAudioOutSourceDevice)inputSelector;
}
else if (OutputCard is Card.Dmps3HdmiOutputBackend)
{
(OutputCard as Card.Dmps3HdmiOutputBackend).AudioOutSourceDevice = (eDmps34KAudioOutSourceDevice)inputSelector;
}
}
}
#endregion
}
}

View file

@ -46,6 +46,8 @@ namespace PepperDash.Essentials.DM
public eDmps3InputVideoSource ActualVideoInput public eDmps3InputVideoSource ActualVideoInput
{ {
get get
{
try
{ {
if (InputCard.VideoSourceFeedback != eDmps3InputVideoSource.Auto) if (InputCard.VideoSourceFeedback != eDmps3InputVideoSource.Auto)
return InputCard.VideoSourceFeedback; return InputCard.VideoSourceFeedback;
@ -59,6 +61,11 @@ namespace PepperDash.Essentials.DM
return eDmps3InputVideoSource.Bnc; return eDmps3InputVideoSource.Bnc;
} }
} }
catch
{
return eDmps3InputVideoSource.Bnc;
}
}
} }
public virtual RoutingPortCollection<RoutingInputPort> InputPorts public virtual RoutingPortCollection<RoutingInputPort> InputPorts

View file

@ -38,6 +38,9 @@ namespace PepperDash.Essentials.DM
void Dmps_MicrophoneChange(MicrophoneBase mic, GenericEventArgs args) void Dmps_MicrophoneChange(MicrophoneBase mic, GenericEventArgs args)
{ {
if (args.EventId == MicrophoneEventIds.VuFeedBackEventId)
return;
Debug.Console(2, "Dmps Microphone Controller Index: {0} EventId: {1}", mic.ID, args.EventId.ToString()); Debug.Console(2, "Dmps Microphone Controller Index: {0} EventId: {1}", mic.ID, args.EventId.ToString());
if(Mics.ContainsKey(mic.ID)) if(Mics.ContainsKey(mic.ID))

View file

@ -27,9 +27,6 @@ namespace PepperDash.Essentials.DM
public ISystemControl SystemControl { get; private set; } public ISystemControl SystemControl { get; private set; }
public bool? EnableRouting { get; private set; } public bool? EnableRouting { get; private set; }
//Check if DMPS is a DMPS3-4K type for endpoint creation
public bool Dmps4kType { get; private set; }
//IroutingNumericEvent //IroutingNumericEvent
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange; public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
@ -62,6 +59,7 @@ namespace PepperDash.Essentials.DM
public Dictionary<uint, string> InputNames { get; set; } public Dictionary<uint, string> InputNames { get; set; }
public Dictionary<uint, string> OutputNames { get; set; } public Dictionary<uint, string> OutputNames { get; set; }
public Dictionary<uint, DmCardAudioOutputController> VolumeControls { get; private set; } public Dictionary<uint, DmCardAudioOutputController> VolumeControls { get; private set; }
public Dictionary<uint, DmpsDigitalOutputController> DigitalAudioOutputs { get; private set; }
public DmpsMicrophoneController Microphones { get; private set; } public DmpsMicrophoneController Microphones { get; private set; }
public const int RouteOffTime = 500; public const int RouteOffTime = 500;
@ -130,7 +128,6 @@ namespace PepperDash.Essentials.DM
{ {
case eSystemControlType.Dmps34K150CSystemControl: case eSystemControlType.Dmps34K150CSystemControl:
SystemControl = systemControl as Dmps34K150CSystemControl; SystemControl = systemControl as Dmps34K150CSystemControl;
Dmps4kType = true;
SystemPowerOnFeedback = new BoolFeedback(() => { return true; }); SystemPowerOnFeedback = new BoolFeedback(() => { return true; });
SystemPowerOffFeedback = new BoolFeedback(() => { return false; }); SystemPowerOffFeedback = new BoolFeedback(() => { return false; });
break; break;
@ -139,13 +136,11 @@ namespace PepperDash.Essentials.DM
case eSystemControlType.Dmps34K300CSystemControl: case eSystemControlType.Dmps34K300CSystemControl:
case eSystemControlType.Dmps34K350CSystemControl: case eSystemControlType.Dmps34K350CSystemControl:
SystemControl = systemControl as Dmps34K300CSystemControl; SystemControl = systemControl as Dmps34K300CSystemControl;
Dmps4kType = true;
SystemPowerOnFeedback = new BoolFeedback(() => { return true; }); SystemPowerOnFeedback = new BoolFeedback(() => { return true; });
SystemPowerOffFeedback = new BoolFeedback(() => { return false; }); SystemPowerOffFeedback = new BoolFeedback(() => { return false; });
break; break;
default: default:
SystemControl = systemControl as Dmps3SystemControl; SystemControl = systemControl as Dmps3SystemControl;
Dmps4kType = false;
SystemPowerOnFeedback = new BoolFeedback(() => SystemPowerOnFeedback = new BoolFeedback(() =>
{ {
return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue; return ((Dmps3SystemControl)SystemControl).SystemPowerOnFeedBack.BoolValue;
@ -156,11 +151,12 @@ namespace PepperDash.Essentials.DM
}); });
break; break;
} }
Debug.Console(1, this, "DMPS Type = {0}, 4K Type = {1}", systemControl.SystemControlType, Dmps4kType); Debug.Console(1, this, "DMPS Type = {0}, 4K Type = {1}", systemControl.SystemControlType, Global.ControlSystemIsDmps4kType);
InputPorts = new RoutingPortCollection<RoutingInputPort>(); InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>(); OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
VolumeControls = new Dictionary<uint, DmCardAudioOutputController>(); VolumeControls = new Dictionary<uint, DmCardAudioOutputController>();
DigitalAudioOutputs = new Dictionary<uint, DmpsDigitalOutputController>();
TxDictionary = new Dictionary<uint, string>(); TxDictionary = new Dictionary<uint, string>();
RxDictionary = new Dictionary<uint, string>(); RxDictionary = new Dictionary<uint, string>();
@ -252,16 +248,18 @@ namespace PepperDash.Essentials.DM
{ {
return; return;
} }
foreach (var kvp in OutputNames) foreach (var kvp in OutputNames)
{ {
var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput); var output = (Dmps.SwitcherOutputs[kvp.Key] as DMOutput);
if (output != null && output.Name.Type != eSigType.NA) if (output != null)
{
if (output.Name.Supported && kvp.Value.Length > 0)
{ {
output.Name.StringValue = kvp.Value; output.Name.StringValue = kvp.Value;
} }
} }
} }
}
private void SetInputNames() private void SetInputNames()
{ {
@ -272,12 +270,15 @@ namespace PepperDash.Essentials.DM
foreach (var kvp in InputNames) foreach (var kvp in InputNames)
{ {
var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput); var input = (Dmps.SwitcherInputs[kvp.Key] as DMInput);
if (input != null && input.Name.Type != eSigType.NA) if (input != null)
{
if (input.Name.Supported && kvp.Value.Length > 0)
{ {
input.Name.StringValue = kvp.Value; input.Name.StringValue = kvp.Value;
} }
} }
} }
}
public void SetRoutingEnable(bool enable) public void SetRoutingEnable(bool enable)
{ {
@ -382,10 +383,22 @@ namespace PepperDash.Essentials.DM
} }
if (OutputNameFeedbacks[ioSlot] != null) if (OutputNameFeedbacks[ioSlot] != null)
{ {
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]); if (Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3DmOutput ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3DmOutputBackend ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3HdmiOutput ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3HdmiOutputBackend ||
Dmps.SwitcherOutputs[ioSlot].CardInputOutputType == eCardInputOutputType.Dmps3DmHdmiAudioOutput)
{
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputVideoNames.JoinNumber + ioSlotJoin]); OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputVideoNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]); OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]);
} }
else
{
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + ioSlotJoin]);
OutputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.OutputAudioNames.JoinNumber + ioSlotJoin]);
}
}
if (OutputVideoRouteNameFeedbacks[ioSlot] != null) if (OutputVideoRouteNameFeedbacks[ioSlot] != null)
{ {
OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig( OutputVideoRouteNameFeedbacks[ioSlot].LinkInputSig(
@ -406,13 +419,11 @@ namespace PepperDash.Essentials.DM
private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap) private void LinkInputsToApi(BasicTriList trilist, DmpsRoutingControllerJoinMap joinMap)
{ {
if (Dmps4kType) if (Global.ControlSystemIsDmps4k3xxType)
{ {
//DMPS-4K audio inputs 1-5 are aux inputs //Add DMPS-4K mixer input names to end of inputs
for (uint i = 1; i <= 5; i++) trilist.StringInput[joinMap.InputAudioNames.JoinNumber + (uint)Dmps.SwitcherInputs.Count + 4].StringValue = "Digital Mixer 1";
{ trilist.StringInput[joinMap.InputAudioNames.JoinNumber + (uint)Dmps.SwitcherInputs.Count + 5].StringValue = "Digital Mixer 2";
trilist.StringInput[joinMap.InputAudioNames.JoinNumber + i - 1].StringValue = String.Format("Aux Input {0}", i);
}
} }
for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++) for (uint i = 1; i <= Dmps.SwitcherInputs.Count; i++)
{ {
@ -429,16 +440,17 @@ namespace PepperDash.Essentials.DM
if (InputNameFeedbacks.ContainsKey(ioSlot) && InputNameFeedbacks[ioSlot] != null) if (InputNameFeedbacks.ContainsKey(ioSlot) && InputNameFeedbacks[ioSlot] != null)
{ {
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]); if (Dmps.SwitcherInputs[ioSlot] is Card.Dmps3AnalogAudioInput)
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputVideoNames.JoinNumber + ioSlotJoin]);
if (Dmps4kType)
{ {
//DMPS-4K Audio Inputs are offset by 5 for (uint j = ioSlot; j < ioSlot + 5; j++)
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin + 5]); {
InputNameFeedbacks[j].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + j - 1]);
}
} }
else else
{ {
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputNames.JoinNumber + ioSlotJoin]);
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputVideoNames.JoinNumber + ioSlotJoin]);
InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin]); InputNameFeedbacks[ioSlot].LinkInputSig(trilist.StringInput[joinMap.InputAudioNames.JoinNumber + ioSlotJoin]);
} }
} }
@ -480,6 +492,8 @@ namespace PepperDash.Essentials.DM
void SetupOutputCards() void SetupOutputCards()
{ {
foreach (var card in Dmps.SwitcherOutputs) foreach (var card in Dmps.SwitcherOutputs)
{
try
{ {
Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType); Debug.Console(1, this, "Output Card Type: {0}", card.CardInputOutputType);
@ -500,23 +514,66 @@ namespace PepperDash.Essentials.DM
}); });
AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() => AudioOutputFeedbacks[outputCard.Number] = new IntFeedback(() =>
{ {
try if (!Global.ControlSystemIsDmps4k3xxType)
{ {
if (outputCard.AudioOutFeedback != null) if (outputCard.AudioOutFeedback != null)
{ {
return (ushort) outputCard.AudioOutFeedback.Number; return (ushort)outputCard.AudioOutFeedback.Number;
} }
return 0; return 0;
} }
catch (NotSupportedException) else
{ {
return (ushort) outputCard.AudioOutSourceFeedback;
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
//Special cases for DMPS-4K digital audio output
if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 0)
return 0;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 1)
return (ushort)Dmps.SwitcherInputs.Count + 5;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 2)
return (ushort)Dmps.SwitcherInputs.Count + 6;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 3)
return (ushort)outputCard.VideoOutFeedback.Number;
else
return 0;
}
else if (outputCard.AudioOutSourceFeedback == eDmps34KAudioOutSource.NoRoute)
{
//Fixes for weird audio indexing on DMPS3-4K
return 0;
}
else if (outputCard.AudioOutSourceFeedback == eDmps34KAudioOutSource.AirMedia8)
{
//Fixes for weird audio indexing on DMPS3-4K
return 8;
}
else if (outputCard.AudioOutSourceFeedback == eDmps34KAudioOutSource.AirMedia9)
{
//Fixes for weird audio indexing on DMPS3-4K
return 9;
}
else if ((ushort)outputCard.AudioOutSourceFeedback <= 5)
{
//Move analog inputs to after regular dm cards
return (ushort)outputCard.AudioOutSourceFeedback + (ushort)Dmps.SwitcherInputs.Count - 1;
}
else
{
//Fixes for weird audio indexing on DMPS3-4K
return (ushort)outputCard.AudioOutSourceFeedback - 5;
}
} }
}); });
OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() => OutputNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{ {
if (outputCard.NameFeedback != null && outputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue)) if(OutputNames.ContainsKey(outputCard.Number))
{
return OutputNames[outputCard.Number];
}
else if (outputCard.NameFeedback != null && outputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(outputCard.NameFeedback.StringValue))
{ {
Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue); Debug.Console(2, this, "Output Card {0} Name: {1}", outputCard.Number, outputCard.NameFeedback.StringValue);
return outputCard.NameFeedback.StringValue; return outputCard.NameFeedback.StringValue;
@ -533,11 +590,35 @@ namespace PepperDash.Essentials.DM
return NoRouteText; return NoRouteText;
}); });
OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() => OutputAudioRouteNameFeedbacks[outputCard.Number] = new StringFeedback(() =>
{
if (!Global.ControlSystemIsDmps4k3xxType)
{ {
if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null) if (outputCard.AudioOutFeedback != null && outputCard.AudioOutFeedback.NameFeedback != null)
{ {
return outputCard.AudioOutFeedback.NameFeedback.StringValue; return outputCard.AudioOutFeedback.NameFeedback.StringValue;
} }
}
else
{
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
//Special cases for DMPS-4K digital audio output
if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 0)
return NoRouteText;
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 1)
return "Digital Mix 1";
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 2)
return "Digital Mix 2";
else if (DigitalAudioOutputs[outputCard.Number].AudioSourceNumericFeedback.UShortValue == 3)
return outputCard.VideoOutFeedback.NameFeedback.StringValue;
else
return NoRouteText;
}
else
{
return outputCard.AudioOutSourceFeedback.ToString();
}
}
return NoRouteText; return NoRouteText;
}); });
@ -545,6 +626,11 @@ namespace PepperDash.Essentials.DM
AddOutputCard(outputCard.Number, outputCard); AddOutputCard(outputCard.Number, outputCard);
} }
catch (Exception ex)
{
Debug.LogError(Debug.ErrorLogLevel.Error, string.Format("DMPS Controller exception creating output card: {0}", ex));
}
}
} }
/// <summary> /// <summary>
@ -569,13 +655,15 @@ namespace PepperDash.Essentials.DM
InputNameFeedbacks[inputCard.Number] = new StringFeedback(() => InputNameFeedbacks[inputCard.Number] = new StringFeedback(() =>
{ {
if (inputCard.NameFeedback != null && inputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue)) if (InputNames.ContainsKey(inputCard.Number))
{
return InputNames[inputCard.Number];
}
else if (inputCard.NameFeedback != null && inputCard.NameFeedback != CrestronControlSystem.NullStringOutputSig && !string.IsNullOrEmpty(inputCard.NameFeedback.StringValue))
{ {
Debug.Console(2, this, "Input Card {0} Name: {1}", inputCard.Number, inputCard.NameFeedback.StringValue); Debug.Console(2, this, "Input Card {0} Name: {1}", inputCard.Number, inputCard.NameFeedback.StringValue);
return inputCard.NameFeedback.StringValue; return inputCard.NameFeedback.StringValue;
} }
Debug.Console(2, this, "Input Card {0} Name is null", inputCard.Number);
return ""; return "";
}); });
@ -609,7 +697,6 @@ namespace PepperDash.Essentials.DM
else if (inputCard is Card.Dmps3HdmiInput) else if (inputCard is Card.Dmps3HdmiInput)
{ {
var hdmiInputCard = inputCard as Card.Dmps3HdmiInput; var hdmiInputCard = inputCard as Card.Dmps3HdmiInput;
var cecPort = hdmiInputCard.HdmiInputPort; var cecPort = hdmiInputCard.HdmiInputPort;
AddInputPortWithDebug(number, string.Format("HdmiIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort); AddInputPortWithDebug(number, string.Format("HdmiIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, cecPort);
@ -641,17 +728,37 @@ namespace PepperDash.Essentials.DM
else if (inputCard is Card.Dmps3DmInput) else if (inputCard is Card.Dmps3DmInput)
{ {
var hdmiInputCard = inputCard as Card.Dmps3DmInput; var hdmiInputCard = inputCard as Card.Dmps3DmInput;
var cecPort = hdmiInputCard.DmInputPort; var cecPort = hdmiInputCard.DmInputPort;
AddInputPortWithDebug(number, string.Format("DmIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort); AddInputPortWithDebug(number, string.Format("DmIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.DmCat, cecPort);
} }
else if (inputCard is Card.Dmps3VgaInput)
{
AddInputPortWithDebug(number, string.Format("VgaIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Vga);
}
else if (inputCard is Card.Dmps3AirMediaInput) else if (inputCard is Card.Dmps3AirMediaInput)
{ {
var airMediaInputCard = inputCard as Card.Dmps3AirMediaInput;
AddInputPortWithDebug(number, string.Format("AirMediaIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming); AddInputPortWithDebug(number, string.Format("AirMediaIn{0}", number), eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Streaming);
} }
else if (inputCard is Card.Dmps3AnalogAudioInput)
{
for (uint i = 0; i <= 4; i++)
{
uint j = i + 1;
uint input = i + number;
InputNameFeedbacks[input] = new StringFeedback(() =>
{
if (InputNames.ContainsKey(input))
{
return InputNames[input];
}
else
{
return String.Format("Aux Input {0}", j);
}
});
}
}
} }
@ -697,22 +804,44 @@ namespace PepperDash.Essentials.DM
var cecPort = hdmiOutputCard.HdmiOutputPort; var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort); AddHdmiOutputPort(number, cecPort);
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Hdmi Audio Output {0}", number), outputCard as Card.Dmps3HdmiOutput);
DeviceManager.AddDevice(audioOutput);
} }
else if (outputCard is Card.Dmps3HdmiOutputBackend) else if (outputCard is Card.Dmps3HdmiOutputBackend)
{ {
var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend; var hdmiOutputCard = outputCard as Card.Dmps3HdmiOutputBackend;
var cecPort = hdmiOutputCard.HdmiOutputPort; var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort); AddHdmiOutputPort(number, cecPort);
var audioOutput = new DmpsDigitalOutputController(string.Format("processor-avRouting-HdmiAudioOut{0}", number), string.Format("Hdmi Audio Output {0} Router", number), hdmiOutputCard);
DigitalAudioOutputs.Add(number, audioOutput);
DeviceManager.AddDevice(audioOutput);
} }
else if (outputCard is Card.Dmps3DmOutput) else if (outputCard is Card.Dmps3DmOutput)
{ {
AddDmOutputPort(number); AddDmOutputPort(number);
var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Dm Audio Output {0}", number), outputCard as Card.Dmps3DmOutput);
DeviceManager.AddDevice(audioOutput);
} }
else if (outputCard is Card.Dmps3DmOutputBackend) else if (outputCard is Card.Dmps3DmOutputBackend)
{ {
AddDmOutputPort(number); AddDmOutputPort(number);
var audioOutput = new DmpsDigitalOutputController(string.Format("processor-avRouting-DmAudioOut{0}", number), string.Format("Dm Audio Output {0} Router", number), outputCard as Card.Dmps3DmOutputBackend);
DigitalAudioOutputs.Add(number, audioOutput);
DeviceManager.AddDevice(audioOutput);
}
else if (outputCard is Card.Dmps3DmHdmiAudioOutput)
{
var hdmiOutputCard = outputCard as Card.Dmps3DmHdmiAudioOutput;
var cecPort = hdmiOutputCard.HdmiOutputPort;
AddHdmiOutputPort(number, cecPort);
AddDmOutputPort(number);
AddAudioOnlyOutputPort(number, "Program");
var audioOutput = new DmpsAudioOutputController(string.Format("processor-programAudioOutput", number), string.Format("Program Audio Output {0}", number), hdmiOutputCard, hdmiOutputCard.AudioOutputStream);
DeviceManager.AddDevice(audioOutput);
var digitalAudioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number), string.Format("Hdmi Audio Output {0}", number), hdmiOutputCard, hdmiOutputCard.DmHdmiOutputStream);
DeviceManager.AddDevice(digitalAudioOutput);
} }
else if (outputCard is Card.Dmps3ProgramOutput) else if (outputCard is Card.Dmps3ProgramOutput)
{ {
@ -730,7 +859,7 @@ namespace PepperDash.Essentials.DM
{ {
AddAudioOnlyOutputPort(number, "Aux1"); AddAudioOnlyOutputPort(number, "Aux1");
var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3Aux1Output); var aux1Output = new DmpsAudioOutputController(string.Format("processor-aux1AudioOutput"), "Aux1 Audio Output", outputCard as Card.Dmps3Aux1Output);
DeviceManager.AddDevice(aux1Output); DeviceManager.AddDevice(aux1Output);
} }
@ -739,7 +868,7 @@ namespace PepperDash.Essentials.DM
{ {
AddAudioOnlyOutputPort(number, "Aux2"); AddAudioOnlyOutputPort(number, "Aux2");
var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Program Audio Output", outputCard as Card.Dmps3Aux2Output); var aux2Output = new DmpsAudioOutputController(string.Format("processor-aux2AudioOutput"), "Aux2 Audio Output", outputCard as Card.Dmps3Aux2Output);
DeviceManager.AddDevice(aux2Output); DeviceManager.AddDevice(aux2Output);
} }
@ -766,6 +895,10 @@ namespace PepperDash.Essentials.DM
{ {
AddAudioOnlyOutputPort(number, "Dialer"); AddAudioOnlyOutputPort(number, "Dialer");
} }
else if (outputCard is Card.Dmps3AecOutput)
{
AddAudioOnlyOutputPort(number, "Aec");
}
else if (outputCard is Card.Dmps3DigitalMixOutput) else if (outputCard is Card.Dmps3DigitalMixOutput)
{ {
if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix1 if (number == (uint)CrestronControlSystem.eDmps34K250COutputs.Mix1
@ -776,10 +909,9 @@ namespace PepperDash.Essentials.DM
|| number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2 || number == (uint)CrestronControlSystem.eDmps34K300COutputs.Mix2
|| number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2) || number == (uint)CrestronControlSystem.eDmps34K350COutputs.Mix2)
AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString()); AddAudioOnlyOutputPort(number, CrestronControlSystem.eDmps34K250COutputs.Mix2.ToString());
}
else if (outputCard is Card.Dmps3AecOutput) var audioOutput = new DmpsAudioOutputController(string.Format("processor-digitalAudioOutput{0}", number % 2 + 1), string.Format("Digital Audio Mix {0}", number % 2 + 1), outputCard as Card.Dmps3DigitalMixOutput);
{ DeviceManager.AddDevice(audioOutput);
AddAudioOnlyOutputPort(number, "Aec");
} }
else else
{ {
@ -851,6 +983,7 @@ namespace PepperDash.Essentials.DM
void Dmps_DMInputChange(Switch device, DMInputEventArgs args) void Dmps_DMInputChange(Switch device, DMInputEventArgs args)
{ {
Debug.Console(2, this, "DMInputChange Input: {0} EventId: {1}", args.Number, args.EventId.ToString());
try try
{ {
switch (args.EventId) switch (args.EventId)
@ -861,6 +994,12 @@ namespace PepperDash.Essentials.DM
InputEndpointOnlineFeedbacks[args.Number].FireUpdate(); InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break; break;
} }
case (DMInputEventIds.EndpointOnlineEventId):
{
Debug.Console(2, this, "DM Input EndpointOnlineEventId for input: {0}. State: {1}", args.Number, device.Inputs[args.Number].EndpointOnlineFeedback);
InputEndpointOnlineFeedbacks[args.Number].FireUpdate();
break;
}
case (DMInputEventIds.VideoDetectedEventId): case (DMInputEventIds.VideoDetectedEventId):
{ {
Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number); Debug.Console(2, this, "DM Input {0} VideoDetectedEventId", args.Number);
@ -885,14 +1024,13 @@ namespace PepperDash.Essentials.DM
} }
void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args) void Dmps_DMOutputChange(Switch device, DMOutputEventArgs args)
{ {
Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString());
if (args.EventId == DMOutputEventIds.OutputVuFeedBackEventId) if (args.EventId == DMOutputEventIds.OutputVuFeedBackEventId)
{ {
//Frequently called event that isn't needed //Frequently called event that isn't needed
return; return;
} }
Debug.Console(2, this, "DMOutputChange Output: {0} EventId: {1}", args.Number, args.EventId.ToString());
var output = args.Number; var output = args.Number;
DMOutput outputCard = Dmps.SwitcherOutputs[output] as DMOutput; DMOutput outputCard = Dmps.SwitcherOutputs[output] as DMOutput;
@ -906,6 +1044,11 @@ namespace PepperDash.Essentials.DM
{ {
OutputEndpointOnlineFeedbacks[output].FireUpdate(); OutputEndpointOnlineFeedbacks[output].FireUpdate();
} }
else if (args.EventId == DMOutputEventIds.EndpointOnlineEventId
&& OutputEndpointOnlineFeedbacks.ContainsKey(output))
{
OutputEndpointOnlineFeedbacks[output].FireUpdate();
}
else if (args.EventId == DMOutputEventIds.VideoOutEventId) else if (args.EventId == DMOutputEventIds.VideoOutEventId)
{ {
if (outputCard != null && outputCard.VideoOutFeedback != null) if (outputCard != null && outputCard.VideoOutFeedback != null)
@ -920,41 +1063,68 @@ namespace PepperDash.Essentials.DM
{ {
OutputVideoRouteNameFeedbacks[output].FireUpdate(); OutputVideoRouteNameFeedbacks[output].FireUpdate();
} }
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
}
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
{
OutputAudioRouteNameFeedbacks[output].FireUpdate();
}
}
} }
else if (args.EventId == DMOutputEventIds.AudioOutEventId) else if (args.EventId == DMOutputEventIds.AudioOutEventId)
{ {
try if (!Global.ControlSystemIsDmps4k3xxType)
{ {
if (outputCard != null && outputCard.AudioOutFeedback != null) if (outputCard != null && outputCard.AudioOutFeedback != null)
{ {
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name, Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", this.Name,
outputCard.AudioOutFeedback.Number, output); outputCard.AudioOutFeedback.Number, output);
} }
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
} }
} else
catch (NotSupportedException)
{ {
if (outputCard != null) if (outputCard != null)
{
if (outputCard is Card.Dmps3DmOutputBackend || outputCard is Card.Dmps3HdmiOutputBackend)
{
DigitalAudioOutputs[output].AudioSourceNumericFeedback.FireUpdate();
}
else
{ {
Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name, Debug.Console(2, this, "DMSwitchAudio:{0} Routed Input:{1} Output:{2}'", Name,
outputCard.AudioOutSourceFeedback, output); outputCard.AudioOutSourceFeedback, output);
} }
}
}
if (AudioOutputFeedbacks.ContainsKey(output)) if (AudioOutputFeedbacks.ContainsKey(output))
{ {
AudioOutputFeedbacks[output].FireUpdate(); AudioOutputFeedbacks[output].FireUpdate();
} }
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
{
OutputAudioRouteNameFeedbacks[output].FireUpdate();
} }
} }
else if (args.EventId == DMOutputEventIds.OutputNameEventId else if (args.EventId == DMOutputEventIds.OutputNameEventId
&& OutputNameFeedbacks.ContainsKey(output)) && OutputNameFeedbacks.ContainsKey(output))
{ {
Debug.Console(2, this, "DM Output {0} NameFeedbackEventId", output);
OutputNameFeedbacks[output].FireUpdate(); OutputNameFeedbacks[output].FireUpdate();
} }
else if (args.EventId == DMOutputEventIds.DigitalMixerAudioSourceFeedBackEventId)
{
if (AudioOutputFeedbacks.ContainsKey(output))
{
AudioOutputFeedbacks[output].FireUpdate();
}
if (OutputAudioRouteNameFeedbacks.ContainsKey(output))
{
OutputAudioRouteNameFeedbacks[output].FireUpdate();
}
}
} }
void Dmps_DMSystemChange(Switch device, DMSystemEventArgs args) void Dmps_DMSystemChange(Switch device, DMSystemEventArgs args)
@ -1002,9 +1172,6 @@ namespace PepperDash.Essentials.DM
Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType); Debug.Console(2, this, "Attempting a DM route from input {0} to output {1} {2}", inputSelector, outputSelector, sigType);
//var input = Convert.ToUInt32(inputSelector); // Cast can sometimes fail
//var output = Convert.ToUInt32(outputSelector);
var input = inputSelector as DMInput; var input = inputSelector as DMInput;
var output = outputSelector as DMOutput; var output = outputSelector as DMOutput;
@ -1022,7 +1189,7 @@ namespace PepperDash.Essentials.DM
if (input == null || (input.Number <= Dmps.NumberOfSwitcherInputs && output.Number <= Dmps.NumberOfSwitcherOutputs && if (input == null || (input.Number <= Dmps.NumberOfSwitcherInputs && output.Number <= Dmps.NumberOfSwitcherOutputs &&
sigTypeIsUsbOrVideo) || sigTypeIsUsbOrVideo) ||
(input.Number <= Dmps.NumberOfSwitcherInputs + 5 && output.Number <= Dmps.NumberOfSwitcherOutputs && (input.Number <= (Dmps.NumberOfSwitcherInputs) && output.Number <= Dmps.NumberOfSwitcherOutputs &&
(sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)) (sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio))
{ {
// Check to see if there's an off timer waiting on this and if so, cancel // Check to see if there's an off timer waiting on this and if so, cancel
@ -1041,11 +1208,6 @@ namespace PepperDash.Essentials.DM
} }
} }
//DMOutput dmOutputCard = output == 0 ? null : Dmps.SwitcherOutputs[output] as DMOutput;
//if (inCard != null)
//{
// NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES // NOTE THAT BITWISE COMPARISONS - TO CATCH ALL ROUTING TYPES
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video) if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{ {
@ -1054,19 +1216,34 @@ namespace PepperDash.Essentials.DM
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio) if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{ {
try if (!Global.ControlSystemIsDmps4k3xxType)
{ {
output.AudioOut = input; output.AudioOut = input;
} }
catch (NotSupportedException) else
{ {
Debug.Console(1, this, "Routing input {0} audio to output {1}", if (input == null)
(eDmps34KAudioOutSource) (input == null ? 0 : input.Number), {
(CrestronControlSystem.eDmps34K350COutputs) output.Number); output.AudioOutSource = eDmps34KAudioOutSource.NoRoute;
}
output.AudioOutSource = input == null else if (input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaInput || input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaNoStreamingInput)
? eDmps34KAudioOutSource.NoRoute {
: (eDmps34KAudioOutSource)input.Number; //Special case for weird AirMedia indexing
if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia8;
else if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia9;
}
else if (input.Number < Dmps.SwitcherInputs.Count)
{
//Shift video inputs by 5 for weird DMPS3-4K indexing
output.AudioOutSource = (eDmps34KAudioOutSource)(input.Number + 5);
}
else
{
//Shift analog inputs back to inputs 1-5
output.AudioOutSource = (eDmps34KAudioOutSource)(input.Number - Dmps.SwitcherInputs.Count + 1);
}
} }
} }
@ -1099,12 +1276,93 @@ namespace PepperDash.Essentials.DM
#region IRoutingNumeric Members #region IRoutingNumeric Members
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType) public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType sigType)
{
if (EnableRouting == false)
{
return;
}
Debug.Console(1, this, "Attempting a numeric switch from input {0} to output {1} {2}", inputSelector, outputSelector, sigType);
if((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
if (inputSelector <= Dmps.SwitcherInputs.Count && outputSelector <= Dmps.SwitcherOutputs.Count)
{ {
var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector]; var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector];
var output = Dmps.SwitcherOutputs[outputSelector]; var output = Dmps.SwitcherOutputs[outputSelector];
ExecuteSwitch(input, output, sigType); ExecuteSwitch(input, output, sigType);
} }
}
else if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
//Special case for DMPS-4K digital audio output
if (Global.ControlSystemIsDmps4k3xxType)
{
if (DigitalAudioOutputs.ContainsKey(outputSelector))
{
if (inputSelector == 0) //Clear action
{
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(0, 0, eRoutingSignalType.Audio);
}
else if (inputSelector < Dmps.SwitcherInputs.Count) //DMPS-4K video inputs, set to audio follows video
{
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(3, 0, eRoutingSignalType.Audio);
//Force video route since it is now set so audio follows video
ExecuteNumericSwitch(inputSelector, outputSelector, eRoutingSignalType.Video);
}
else if (inputSelector == Dmps.SwitcherInputs.Count + 5)
{
//Set to mix 1
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(1, 0, eRoutingSignalType.Audio);
}
else if (inputSelector == Dmps.SwitcherInputs.Count + 6)
{
//Set to mix 2
DigitalAudioOutputs[outputSelector].ExecuteNumericSwitch(2, 0, eRoutingSignalType.Audio);
}
}
else if (inputSelector <= (Dmps.SwitcherInputs.Count + 4) && outputSelector <= Dmps.SwitcherOutputs.Count)
{
var output = Dmps.SwitcherOutputs[outputSelector] as DMOutput;
if (inputSelector == 0)
{
output.AudioOutSource = eDmps34KAudioOutSource.NoRoute;
}
else if(inputSelector >= (Dmps.SwitcherInputs.Count))
{
//Shift analog inputs back to inputs 1-5
Debug.Console(1, this, "Attempting analog route input {0} to output {1}", inputSelector - Dmps.SwitcherInputs.Count + 1, outputSelector);
output.AudioOutSource = (eDmps34KAudioOutSource)(inputSelector - Dmps.SwitcherInputs.Count + 1);
}
else if (inputSelector < Dmps.SwitcherInputs.Count)
{
var input = Dmps.SwitcherInputs[inputSelector] as DMInput;
if (input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaInput || input.CardInputOutputType == eCardInputOutputType.Dmps3AirMediaNoStreamingInput)
{
//Special case for weird AirMedia indexing
if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K250CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia8;
else if (Dmps.SystemControl.SystemControlType == eSystemControlType.Dmps34K350CSystemControl)
output.AudioOutSource = eDmps34KAudioOutSource.AirMedia9;
}
else
{
//Shift video inputs by 5 for weird DMPS3-4K indexing
output.AudioOutSource = (eDmps34KAudioOutSource)(inputSelector + 5);
}
}
}
}
else if (inputSelector <= Dmps.SwitcherInputs.Count && outputSelector <= Dmps.SwitcherOutputs.Count)
{
var output = Dmps.SwitcherOutputs[outputSelector] as DMOutput;
var input = inputSelector == 0 ? null : Dmps.SwitcherInputs[inputSelector] as DMInput;
output.AudioOut = input;
}
}
}
#endregion #endregion
} }

View file

@ -0,0 +1,516 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.DM.Config;
using Crestron.SimplSharpPro.DM.Cards;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.DM.Chassis
{
[Description("Wrapper class for all HdMd8xN switchers")]
public class HdMd8xNController : CrestronGenericBridgeableBaseDevice, IRoutingNumericWithFeedback, IHasFeedback
{
private HdMd8xN _Chassis;
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
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 FeedbackCollection<BoolFeedback> VideoInputSyncFeedbacks { get; private set; }
public FeedbackCollection<IntFeedback> VideoOutputRouteFeedbacks { get; private set; }
public FeedbackCollection<IntFeedback> AudioOutputRouteFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> InputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputVideoRouteNameFeedbacks { get; private set; }
public FeedbackCollection<StringFeedback> OutputAudioRouteNameFeedbacks { get; private set; }
public StringFeedback DeviceNameFeedback { get; private set; }
#region Constructor
public HdMd8xNController(string key, string name, HdMd8xN chassis,
DMChassisPropertiesConfig props)
: base(key, name, chassis)
{
_Chassis = chassis;
Name = name;
_Chassis.EnableAudioBreakaway.BoolValue = true;
if (props == null)
{
Debug.Console(1, this, "HdMd8xNController properties are null, failed to build the device");
return;
}
InputNames = new Dictionary<uint, string>();
if (props.InputNames != null)
{
InputNames = props.InputNames;
}
OutputNames = new Dictionary<uint, string>();
if (props.OutputNames != null)
{
OutputNames = props.OutputNames;
}
DeviceNameFeedback = new StringFeedback(()=> Name);
VideoInputSyncFeedbacks = new FeedbackCollection<BoolFeedback>();
VideoOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
AudioOutputRouteFeedbacks = new FeedbackCollection<IntFeedback>();
InputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputVideoRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
OutputAudioRouteNameFeedbacks = new FeedbackCollection<StringFeedback>();
InputPorts = new RoutingPortCollection<RoutingInputPort>();
OutputPorts = new RoutingPortCollection<RoutingOutputPort>();
//Inputs - should always be 8 audio/video inputs
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
try
{
var index = i;
if (!InputNames.ContainsKey(index))
{
InputNames.Add(index, string.Format("Input{0}", index));
}
string inputName = InputNames[index];
_Chassis.Inputs[index].Name.StringValue = inputName;
InputPorts.Add(new RoutingInputPort(inputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, _Chassis.Inputs[index], this)
{
FeedbackMatchObject = _Chassis.Inputs[index]
});
VideoInputSyncFeedbacks.Add(new BoolFeedback(inputName, () => _Chassis.Inputs[index].VideoDetectedFeedback.BoolValue));
InputNameFeedbacks.Add(new StringFeedback(inputName, () => _Chassis.Inputs[index].NameFeedback.StringValue));
}
catch (Exception ex)
{
ErrorLog.Error("Exception creating input {0} on HD-MD8xN Chassis: {1}", i, ex);
}
}
//Outputs. Either 2 outputs (1 audio, 1 audio/video) for HD-MD8x1 or 4 outputs (2 audio, 2 audio/video) for HD-MD8x2
for (uint i = 1; i <= _Chassis.NumberOfOutputs; i++)
{
try
{
var index = i;
if (!OutputNames.ContainsKey(index))
{
OutputNames.Add(index, string.Format("Output{0}", index));
}
string outputName = OutputNames[index];
_Chassis.Outputs[index].Name.StringValue = outputName;
OutputPorts.Add(new RoutingOutputPort(outputName, eRoutingSignalType.AudioVideo,
eRoutingPortConnectionType.Hdmi, _Chassis.Outputs[index], this)
{
FeedbackMatchObject = _Chassis.Outputs[index]
});
OutputNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].NameFeedback.StringValue));
VideoOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].VideoOutFeedback.Number));
AudioOutputRouteFeedbacks.Add(new IntFeedback(outputName, () => _Chassis.Outputs[index].AudioOutFeedback == null ? 0 : (int)_Chassis.Outputs[index].AudioOutFeedback.Number));
OutputVideoRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].VideoOutFeedback == null ? "None" : _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
OutputAudioRouteNameFeedbacks.Add(new StringFeedback(outputName, () => _Chassis.Outputs[index].AudioOutFeedback == null ? "None" : _Chassis.Outputs[index].VideoOutFeedback.NameFeedback.StringValue));
}
catch (Exception ex)
{
ErrorLog.Error("Exception creating output {0} on HD-MD8xN Chassis: {1}", i, ex);
}
}
_Chassis.DMInputChange += Chassis_DMInputChange;
_Chassis.DMOutputChange += Chassis_DMOutputChange;
AddPostActivationAction(AddFeedbackCollections);
}
#endregion
#region Methods
/// <summary>
/// Raise an event when the status of a switch object changes.
/// </summary>
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
private void OnSwitchChange(RoutingNumericEventArgs e)
{
var newEvent = NumericSwitchChange;
if (newEvent != null) newEvent(this, e);
}
#region PostActivate
public void AddFeedbackCollections()
{
AddFeedbackToList(DeviceNameFeedback);
AddCollectionsToList(VideoInputSyncFeedbacks);
AddCollectionsToList(VideoOutputRouteFeedbacks, AudioOutputRouteFeedbacks);
AddCollectionsToList(InputNameFeedbacks, OutputNameFeedbacks, OutputVideoRouteNameFeedbacks, OutputAudioRouteNameFeedbacks);
}
#endregion
#region FeedbackCollection Methods
//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);
}
}
}
public void AddCollectionsToList(params FeedbackCollection<StringFeedback>[] newFbs)
{
foreach (FeedbackCollection<StringFeedback> 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;
AddFeedbackToList(f);
}
}
public void AddCollectionToList(FeedbackCollection<IntFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
public void AddCollectionToList(FeedbackCollection<StringFeedback> newFbs)
{
foreach (var f in newFbs)
{
if (f == null) continue;
AddFeedbackToList(f);
}
}
//Add Individual Feedbacks
public void AddFeedbackToList(PepperDash.Essentials.Core.Feedback newFb)
{
if (newFb == null) return;
if (!Feedbacks.Contains(newFb))
{
Feedbacks.Add(newFb);
}
}
#endregion
#region IRouting Members
public void ExecuteSwitch(object inputSelector, object outputSelector, eRoutingSignalType sigType)
{
var input = inputSelector as DMInput;
var output = outputSelector as DMOutput;
Debug.Console(2, this, "ExecuteSwitch: input={0} output={1} sigType={2}", input, output, sigType.ToString());
if (output == null)
{
Debug.Console(0, this, "Unable to make switch. Output selector is not DMOutput");
return;
}
if ((sigType & eRoutingSignalType.Video) == eRoutingSignalType.Video)
{
_Chassis.VideoEnter.BoolValue = true;
if (output != null)
{
output.VideoOut = input;
}
}
if ((sigType & eRoutingSignalType.Audio) == eRoutingSignalType.Audio)
{
_Chassis.AudioEnter.BoolValue = true;
if (output != null)
{
output.AudioOut = input;
}
}
}
#endregion
#region IRoutingNumeric Members
public void ExecuteNumericSwitch(ushort inputSelector, ushort outputSelector, eRoutingSignalType signalType)
{
var input = inputSelector == 0 ? null : _Chassis.Inputs[inputSelector];
var output = _Chassis.Outputs[outputSelector];
Debug.Console(2, this, "ExecuteNumericSwitch: input={0} output={1}", input, output);
ExecuteSwitch(input, output, signalType);
}
#endregion
#endregion
#region Bridge Linking
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmChassisControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmChassisControllerJoinMap>(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]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
for (uint i = 1; i <= _Chassis.NumberOfInputs; i++)
{
var joinIndex = i - 1;
var input = i;
//Digital
VideoInputSyncFeedbacks[InputNames[input]].LinkInputSig(trilist.BooleanInput[joinMap.VideoSyncStatus.JoinNumber + joinIndex]);
//Serial
InputNameFeedbacks[InputNames[input]].LinkInputSig(trilist.StringInput[joinMap.InputNames.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.OutputVideo.JoinNumber + joinIndex]);
trilist.SetUShortSigAction(joinMap.OutputVideo.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort)output, eRoutingSignalType.Video));
AudioOutputRouteFeedbacks[OutputNames[output]].LinkInputSig(trilist.UShortInput[joinMap.OutputAudio.JoinNumber + joinIndex]);
trilist.SetUShortSigAction(joinMap.OutputAudio.JoinNumber + joinIndex, (a) => ExecuteNumericSwitch(a, (ushort)output, eRoutingSignalType.Audio));
//Serial
OutputNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputNames.JoinNumber + joinIndex]);
OutputVideoRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentVideoInputNames.JoinNumber + joinIndex]);
OutputAudioRouteNameFeedbacks[OutputNames[output]].LinkInputSig(trilist.StringInput[joinMap.OutputCurrentAudioInputNames.JoinNumber + joinIndex]);
}
_Chassis.OnlineStatusChange += Chassis_OnlineStatusChange;
trilist.OnlineStatusChange += (d, args) =>
{
if (!args.DeviceOnLine) return;
};
}
#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();
}
}
void Chassis_DMOutputChange(Switch device, DMOutputEventArgs args)
{
switch (args.EventId)
{
case DMOutputEventIds.VideoOutEventId:
{
var output = args.Number;
var inputNumber = _Chassis.Outputs[output].VideoOutFeedback == null ? 0 : _Chassis.Outputs[output].VideoOutFeedback.Number;
var outputName = OutputNames[output];
var feedback = VideoOutputRouteFeedbacks[outputName];
if (feedback == null)
{
return;
}
var inPort = InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output].VideoOutFeedback);
var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output]);
feedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.Video));
break;
}
case DMOutputEventIds.AudioOutEventId:
{
var output = args.Number;
var inputNumber = _Chassis.Outputs[output].AudioOutFeedback == null ? 0 : _Chassis.Outputs[output].AudioOutFeedback.Number;
var outputName = OutputNames[output];
var feedback = AudioOutputRouteFeedbacks[outputName];
if (feedback == null)
{
return;
}
var inPort = InputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output].AudioOutFeedback);
var outPort = OutputPorts.FirstOrDefault(p => p.FeedbackMatchObject == _Chassis.Outputs[output]);
feedback.FireUpdate();
OnSwitchChange(new RoutingNumericEventArgs(output, inputNumber, outPort, inPort, eRoutingSignalType.Audio));
break;
}
case DMOutputEventIds.OutputNameEventId:
case DMOutputEventIds.NameFeedbackEventId:
{
Debug.Console(1, this, "Event ID {0}: Updating name feedbacks.", args.EventId);
Debug.Console(1, this, "Output {0} Name {1}", args.Number,
_Chassis.Outputs[args.Number].NameFeedback.StringValue);
foreach (var item in OutputNameFeedbacks)
{
item.FireUpdate();
}
break;
}
default:
{
Debug.Console(1, this, "Unhandled DM Output Event ID {0}", args.EventId);
break;
}
}
}
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)
{
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.Inputs[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 HdMd8xNControllerFactory : EssentialsDeviceFactory<HdMd8xNController>
{
public HdMd8xNControllerFactory()
{
TypeNames = new List<string>() { "hdmd8x2", "hdmd8x1" };
}
public override EssentialsDevice BuildDevice(DeviceConfig dc)
{
Debug.Console(1, "Factory Attempting to create new HD-MD-8xN Device");
var props = JsonConvert.DeserializeObject<DMChassisPropertiesConfig>(dc.Properties.ToString());
var type = dc.Type.ToLower();
var control = props.Control;
var ipid = control.IpIdInt;
switch (type)
{
case ("hdmd8x2"):
return new HdMd8xNController(dc.Key, dc.Name, new HdMd8x2(ipid, Global.ControlSystem), props);
case ("hdmd8x1"):
return new HdMd8xNController(dc.Key, dc.Name, new HdMd8x1(ipid, Global.ControlSystem), props);
default:
return null;
}
}
}
#endregion
}
}

View file

@ -1,8 +1,10 @@
using Crestron.SimplSharp.Ssh; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
@ -28,6 +30,30 @@ namespace PepperDash.Essentials.DM
OutputPorts = new RoutingPortCollection<RoutingOutputPort> {HDBaseTSink}; OutputPorts = new RoutingPortCollection<RoutingOutputPort> {HDBaseTSink};
} }
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmRmcControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmRmcControllerJoinMap>(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
}
#region IComPorts Members #region IComPorts Members
public CrestronCollection<ComPort> ComPorts { get { return Rmc.ComPorts; } } public CrestronCollection<ComPort> ComPorts { get { return Rmc.ComPorts; } }
public int NumberOfComPorts { get { return Rmc.NumberOfComPorts; } } public int NumberOfComPorts { get { return Rmc.NumberOfComPorts; } }

View file

@ -1,9 +1,11 @@
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DM; using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers; using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Core;
using Newtonsoft.Json;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
@ -33,6 +35,30 @@ namespace PepperDash.Essentials.DM
OutputPorts = new RoutingPortCollection<RoutingOutputPort> {HdmiOut}; OutputPorts = new RoutingPortCollection<RoutingOutputPort> {HdmiOut};
} }
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new DmRmcControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<DmRmcControllerJoinMap>(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
}
#region IIROutputPorts Members #region IIROutputPorts Members
public CrestronCollection<IROutputPort> IROutputPorts { get { return _rmc.IROutputPorts; } } public CrestronCollection<IROutputPort> IROutputPorts { get { return _rmc.IROutputPorts; } }
public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } } public int NumberOfIROutputPorts { get { return _rmc.NumberOfIROutputPorts; } }

View file

@ -30,6 +30,7 @@ namespace PepperDash.Essentials.DM
: base(key, name, device) : base(key, name, device)
{ {
_rmc = device; _rmc = device;
// if wired to a chassis, skip registration step in base class // if wired to a chassis, skip registration step in base class
PreventRegistration = _rmc.DMOutput != null; PreventRegistration = _rmc.DMOutput != null;
@ -37,7 +38,7 @@ namespace PepperDash.Essentials.DM
DeviceInfo = new DeviceInfo(); DeviceInfo = new DeviceInfo();
_rmc.OnlineStatusChange += (currentDevice, args) => { if (args.DeviceOnLine) UpdateDeviceInfo(); }; IsOnline.OutputChange += (currentDevice, args) => { if (args.BoolValue) UpdateDeviceInfo(); };
} }
protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) protected void LinkDmRmcToApi(DmRmcControllerBase rmc, BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
@ -60,7 +61,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); Debug.Console(1, rmc, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
rmc.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = rmc.Name; trilist.StringInput[joinMap.Name.JoinNumber].StringValue = rmc.Name;
if (rmc.VideoOutputResolutionFeedback != null) if (rmc.VideoOutputResolutionFeedback != null)
rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution.JoinNumber]); rmc.VideoOutputResolutionFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentOutputResolution.JoinNumber]);
@ -187,7 +188,7 @@ namespace PepperDash.Essentials.DM
#endregion #endregion
} }
public abstract class DmHdBaseTControllerBase : CrestronGenericBaseDevice public abstract class DmHdBaseTControllerBase : CrestronGenericBridgeableBaseDevice
{ {
protected HDBaseTBase Rmc; protected HDBaseTBase Rmc;
@ -330,24 +331,40 @@ namespace PepperDash.Essentials.DM
var parentDev = DeviceManager.GetDeviceForKey(pKey); var parentDev = DeviceManager.GetDeviceForKey(pKey);
if (parentDev is DmpsRoutingController) if (parentDev is DmpsRoutingController)
{ {
if ((parentDev as DmpsRoutingController).Dmps4kType) var dmps = parentDev as DmpsRoutingController;
//Check that the input is within range of this chassis' possible inputs
var num = props.ParentOutputNumber;
Debug.Console(1, "Creating DMPS device '{0}'. Output number '{1}'.", key, num);
if (num <= 0 || num > dmps.Dmps.SwitcherOutputs.Count)
{ {
return GetDmRmcControllerForDmps4k(key, name, typeName, parentDev as DmpsRoutingController, props.ParentOutputNumber); Debug.Console(0, "Cannot create DMPS device '{0}'. Output number '{1}' is out of range",
} key, num);
else
{
return GetDmRmcControllerForDmps(key, name, typeName, ipid, parentDev as DmpsRoutingController, props.ParentOutputNumber);
}
}
if (!(parentDev is IDmSwitch))
{
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis.",
key, pKey);
return null; return null;
} }
// Must use different constructor for DMPS4K types. No IPID
var chassis = (parentDev as IDmSwitch).Chassis; if (Global.ControlSystemIsDmps4kType || typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
{
var rmc = GetDmRmcControllerForDmps4k(key, name, typeName, dmps, props.ParentOutputNumber);
Debug.Console(0, "DM endpoint output {0} is for Dmps4k, changing online feedback to chassis", num);
rmc.IsOnline.SetValueFunc(() => dmps.OutputEndpointOnlineFeedbacks[num].BoolValue);
dmps.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
{
foreach (var feedback in rmc.Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
return rmc;
}
return GetDmRmcControllerForDmps(key, name, typeName, ipid, dmps, props.ParentOutputNumber);
}
else if (parentDev is DmChassisController)
{
var controller = parentDev as DmChassisController;
var chassis = controller.Chassis;
var num = props.ParentOutputNumber; var num = props.ParentOutputNumber;
Debug.Console(1, "Creating DM Chassis device '{0}'. Output number '{1}'.", key, num);
if (num <= 0 || num > chassis.NumberOfOutputs) if (num <= 0 || num > chassis.NumberOfOutputs)
{ {
@ -355,8 +372,6 @@ namespace PepperDash.Essentials.DM
key, num); key, num);
return null; return null;
} }
var controller = parentDev as IDmSwitch;
controller.RxDictionary.Add(num, key); controller.RxDictionary.Add(num, key);
// Catch constructor failures, mainly dues to IPID // Catch constructor failures, mainly dues to IPID
try try
@ -365,11 +380,22 @@ namespace PepperDash.Essentials.DM
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 || if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps || chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps || chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps ||
chassis is DmMd128x128 || chassis is DmMd64x64) chassis is DmMd128x128 || chassis is DmMd64x64
|| typeName == "hdbasetrx" || typeName == "dmrmc4k100c1g")
{ {
return GetDmRmcControllerForCpu3Chassis(key, name, typeName, chassis, num, parentDev); var rmc = GetDmRmcControllerForCpu3Chassis(key, name, typeName, chassis, num, parentDev);
Debug.Console(0, "DM endpoint output {0} is for Cpu3, changing online feedback to chassis", num);
rmc.IsOnline.SetValueFunc(() => controller.OutputEndpointOnlineFeedbacks[num].BoolValue);
controller.OutputEndpointOnlineFeedbacks[num].OutputChange += (o, a) =>
{
foreach (var feedback in rmc.Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
return rmc;
} }
return GetDmRmcControllerForCpu2Chassis(key, name, typeName, ipid, chassis, num, parentDev); return GetDmRmcControllerForCpu2Chassis(key, name, typeName, ipid, chassis, num, parentDev);
} }
catch (Exception e) catch (Exception e)
@ -378,6 +404,13 @@ namespace PepperDash.Essentials.DM
return null; return null;
} }
} }
else
{
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a DM Chassis or DMPS.",
key, pKey);
return null;
}
}
private static CrestronGenericBaseDevice GetDmRmcControllerForCpu2Chassis(string key, string name, string typeName, private static CrestronGenericBaseDevice GetDmRmcControllerForCpu2Chassis(string key, string name, string typeName,
uint ipid, Switch chassis, uint num, IKeyed parentDev) uint ipid, Switch chassis, uint num, IKeyed parentDev)
@ -490,7 +523,6 @@ namespace PepperDash.Essentials.DM
var props = JsonConvert.DeserializeObject var props = JsonConvert.DeserializeObject
<DmRmcPropertiesConfig>(dc.Properties.ToString()); <DmRmcPropertiesConfig>(dc.Properties.ToString());
return DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props); return DmRmcHelper.GetDmRmcController(dc.Key, dc.Name, type, props);
} }
} }

View file

@ -97,10 +97,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="tx"></param> /// <param name="tx"></param>
public DmTx200Controller(string key, string name, DmTx200C2G tx) public DmTx200Controller(string key, string name, DmTx200C2G tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,

View file

@ -100,10 +100,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="tx"></param> /// <param name="tx"></param>
public DmTx201CController(string key, string name, DmTx201C tx) public DmTx201CController(string key, string name, DmTx201C tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,

View file

@ -102,10 +102,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="tx"></param> /// <param name="tx"></param>
public DmTx201SController(string key, string name, DmTx201S tx) public DmTx201SController(string key, string name, DmTx201S tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiInput = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi,

View file

@ -111,10 +111,11 @@ namespace PepperDash.Essentials.DM
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="tx"></param> /// <param name="tx"></param>
public DmTx401CController(string key, string name, DmTx401C tx) public DmTx401CController(string key, string name, DmTx401C tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn, HdmiIn = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.HDMI, this,

View file

@ -6,6 +6,7 @@ using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Bridges;
using Newtonsoft.Json;
namespace PepperDash.Essentials.DM namespace PepperDash.Essentials.DM
{ {
@ -20,14 +21,6 @@ namespace PepperDash.Essentials.DM
public RoutingInputPort HdmiIn { get; private set; } public RoutingInputPort HdmiIn { get; private set; }
public RoutingOutputPort DmOut { get; private set; } public RoutingOutputPort DmOut { get; private 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 override IntFeedback HdcpSupportAllFeedback { get; protected set; }
//public override ushort HdcpSupportCapability { get; protected set; }
/// <summary> /// <summary>
/// Helps get the "real" inputs, including when in Auto /// Helps get the "real" inputs, including when in Auto
/// </summary> /// </summary>
@ -70,11 +63,34 @@ namespace PepperDash.Essentials.DM
HdmiIn.Port = Tx; HdmiIn.Port = Tx;
PreventRegistration = true; PreventRegistration = true;
var parentDev = DeviceManager.GetDeviceForKey(key);
var num = tx.DMInputOutput.Number;
if (parentDev is DmpsRoutingController)
{
var dmps = parentDev as DmpsRoutingController;
IsOnline.SetValueFunc(() => dmps.InputEndpointOnlineFeedbacks[num].BoolValue);
dmps.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
else if (parentDev is DmChassisController)
{
var controller = parentDev as DmChassisController;
IsOnline.SetValueFunc(() => controller.InputEndpointOnlineFeedbacks[num].BoolValue);
controller.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
} }
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge) public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
{ {
Debug.Console(1, this, "No properties to link. Skipping device {0}", Name); var joinMap = new HDBaseTTxControllerJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject<HDBaseTTxControllerJoinMap>(joinMapSerialized);
this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
} }
#region IIROutputPorts Members #region IIROutputPorts Members

View file

@ -96,10 +96,11 @@ namespace PepperDash.Essentials.DM
} }
} }
public DmTx4k202CController(string key, string name, DmTx4k202C tx) public DmTx4k202CController(string key, string name, DmTx4k202C tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View file

@ -102,10 +102,11 @@ namespace PepperDash.Essentials.DM
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut }; return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
} }
} }
public DmTx4k302CController(string key, string name, DmTx4k302C tx) public DmTx4k302CController(string key, string name, DmTx4k302C tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View file

@ -86,10 +86,11 @@ namespace PepperDash.Essentials.DM
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut }; return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
} }
} }
public DmTx4kz202CController(string key, string name, DmTx4kz202C tx) public DmTx4kz202CController(string key, string name, DmTx4kz202C tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View file

@ -91,10 +91,11 @@ namespace PepperDash.Essentials.DM
return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut }; return new RoutingPortCollection<RoutingOutputPort> { DmOut, HdmiLoopOut };
} }
} }
public DmTx4kz302CController(string key, string name, DmTx4kz302C tx) public DmTx4kz302CController(string key, string name, DmTx4kz302C tx, bool preventRegistration)
: base(key, name, tx) : base(key, name, tx)
{ {
Tx = tx; Tx = tx;
PreventRegistration = preventRegistration;
HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1, HdmiIn1 = new RoutingInputPortWithVideoStatuses(DmPortName.HdmiIn1,
eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this, eRoutingSignalType.Audio | eRoutingSignalType.Video, eRoutingPortConnectionType.Hdmi, eVst.Hdmi1, this,

View file

@ -20,6 +20,63 @@ namespace PepperDash.Essentials.DM
{ {
public class DmTxHelper public class DmTxHelper
{ {
public static BasicDmTxControllerBase GetDmTxForChassisWithoutIpId(string key, string name, string typeName, DMInput dmInput)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(dmInput), true);
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(dmInput), true);
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(dmInput), true);
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(dmInput));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(dmInput));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(dmInput), true);
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(dmInput), true);
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(dmInput), true);
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(dmInput), true);
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(dmInput), true);
if (typeName.StartsWith("hdbasettx"))
new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
return null;
}
public static BasicDmTxControllerBase GetDmTxForChassisWithIpId(string key, string name, string typeName, uint ipid, DMInput dmInput)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, dmInput), true);
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, dmInput), true);
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, dmInput));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, dmInput), true);
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, dmInput), true);
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, dmInput));
return null;
}
/// <summary> /// <summary>
/// A factory method for various DmTxControllers /// A factory method for various DmTxControllers
/// </summary> /// </summary>
@ -42,23 +99,21 @@ namespace PepperDash.Essentials.DM
try try
{ {
if(typeName.StartsWith("dmtx200")) if(typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem)); return new DmTx200Controller(key, name, new DmTx200C2G(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, Global.ControlSystem));
if (typeName.StartsWith("dmtx201c")) if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem)); return new DmTx201CController(key, name, new DmTx201C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx201s")) if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem)); return new DmTx201SController(key, name, new DmTx201S(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4k202")) if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, Global.ControlSystem)); return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4kz202")) if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, Global.ControlSystem)); return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4k302")) if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem)); return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx4kz302")) if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem)); return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, Global.ControlSystem), false);
if (typeName.StartsWith("dmtx401")) if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem)); return new DmTx401CController(key, name, new DmTx401C(ipid, Global.ControlSystem), false);
Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key); Debug.Console(0, "{1} WARNING: Cannot create DM-TX of type: '{0}'", typeName, key);
} }
catch (Exception e) catch (Exception e)
@ -70,12 +125,12 @@ namespace PepperDash.Essentials.DM
var parentDev = DeviceManager.GetDeviceForKey(pKey); var parentDev = DeviceManager.GetDeviceForKey(pKey);
DMInput dmInput; DMInput dmInput;
bool isCpu3 = false; BasicDmTxControllerBase tx;
if (parentDev is IDmSwitch) if (parentDev is DmChassisController)
{ {
// Get the Crestron chassis and link stuff up // Get the Crestron chassis and link stuff up
var switchDev = (parentDev as IDmSwitch); var switchDev = (parentDev as DmChassisController);
var chassis = switchDev.Chassis; var chassis = switchDev.Chassis;
//Check that the input is within range of this chassis' possible inputs //Check that the input is within range of this chassis' possible inputs
@ -90,15 +145,31 @@ namespace PepperDash.Essentials.DM
switchDev.TxDictionary.Add(num, key); switchDev.TxDictionary.Add(num, key);
dmInput = chassis.Inputs[num]; dmInput = chassis.Inputs[num];
try
{
//Determine if IpId is needed for this chassis type //Determine if IpId is needed for this chassis type
if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 || if (chassis is DmMd8x8Cpu3 || chassis is DmMd16x16Cpu3 ||
chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps || chassis is DmMd32x32Cpu3 || chassis is DmMd8x8Cpu3rps ||
chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps || chassis is DmMd16x16Cpu3rps || chassis is DmMd32x32Cpu3rps ||
chassis is DmMd128x128 || chassis is DmMd64x64) chassis is DmMd128x128 || chassis is DmMd64x64)
{ {
isCpu3 = true; tx = GetDmTxForChassisWithoutIpId(key, name, typeName, dmInput);
Debug.Console(0, "DM endpoint output {0} is for Cpu3, changing online feedback to chassis", num);
tx.IsOnline.SetValueFunc(() => switchDev.InputEndpointOnlineFeedbacks[num].BoolValue);
switchDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
return tx;
}
else
{
return GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device for chassis: {1}", key, e);
return null;
} }
} }
else if(parentDev is DmpsRoutingController) else if(parentDev is DmpsRoutingController)
{ {
@ -126,6 +197,27 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is not a DM input", key, num); Debug.Console(0, "Cannot create DMPS device '{0}'. Input number '{1}' is not a DM input", key, num);
return null; return null;
} }
try
{
if(Global.ControlSystemIsDmps4kType)
{
tx = GetDmTxForChassisWithoutIpId(key, name, typeName, dmInput);
Debug.Console(0, "DM endpoint output {0} is for DMPS3-4K, changing online feedback to chassis", num);
tx.IsOnline.SetValueFunc(() => dmpsDev.InputEndpointOnlineFeedbacks[num].BoolValue);
dmpsDev.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => tx.IsOnline.FireUpdate();
return tx;
}
else
{
return GetDmTxForChassisWithIpId(key, name, typeName, ipid, dmInput);
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device for dmps: {1}", key, e);
return null;
}
} }
else else
@ -133,67 +225,6 @@ namespace PepperDash.Essentials.DM
Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey); Debug.Console(0, "Cannot create DM device '{0}'. '{1}' is not a processor, DM Chassis or DMPS.", key, pKey);
return null; return null;
} }
try
{
// Must use different constructor for CPU3 or DMPS3-4K types. No IPID
if (isCpu3 || Global.ControlSystemIsDmps4kType)
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(dmInput));
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(dmInput));
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(dmInput));
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(dmInput));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(dmInput));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(dmInput));
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(dmInput));
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(dmInput));
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(dmInput));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(dmInput));
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(dmInput));
}
else
{
if (typeName.StartsWith("dmtx200"))
return new DmTx200Controller(key, name, new DmTx200C2G(ipid, dmInput));
if (typeName.StartsWith("dmtx201c"))
return new DmTx201CController(key, name, new DmTx201C(ipid, dmInput));
if (typeName.StartsWith("dmtx201s"))
return new DmTx201SController(key, name, new DmTx201S(ipid, dmInput));
if (typeName.StartsWith("dmtx4k100"))
return new DmTx4k100Controller(key, name, new DmTx4K100C1G(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz100"))
return new DmTx4kz100Controller(key, name, new DmTx4kz100C1G(ipid, dmInput));
if (typeName.StartsWith("dmtx4k202"))
return new DmTx4k202CController(key, name, new DmTx4k202C(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz202"))
return new DmTx4kz202CController(key, name, new DmTx4kz202C(ipid, dmInput));
if (typeName.StartsWith("dmtx4k302"))
return new DmTx4k302CController(key, name, new DmTx4k302C(ipid, dmInput));
if (typeName.StartsWith("dmtx4kz302"))
return new DmTx4kz302CController(key, name, new DmTx4kz302C(ipid, dmInput));
if (typeName.StartsWith("dmtx401"))
return new DmTx401CController(key, name, new DmTx401C(ipid, dmInput));
if (typeName.StartsWith("hdbasettx"))
return new HDBaseTTxController(key, name, new HDTx3CB(ipid, dmInput));
}
}
catch (Exception e)
{
Debug.Console(0, "[{0}] WARNING: Cannot create DM-TX device: {1}", key, e);
}
return null;
} }
} }
@ -221,13 +252,16 @@ namespace PepperDash.Essentials.DM
protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware) protected DmTxControllerBase(string key, string name, EndpointTransmitterBase hardware)
: base(key, name, hardware) : base(key, name, hardware)
{ {
// if wired to a chassis or DMPS, skip registration step in base class
if (hardware.DMInput != null || (Global.ControlSystemIsDmpsType && hardware.DMInput != null))
{
this.PreventRegistration = true;
}
AddToFeedbackList(ActiveVideoInputFeedback); AddToFeedbackList(ActiveVideoInputFeedback);
IsOnline.OutputChange += (currentDevice, args) =>
{
foreach (var feedback in Feedbacks)
{
if (feedback != null)
feedback.FireUpdate();
}
};
} }
protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware) protected DmTxControllerBase(string key, string name, DmHDBasedTEndPoint hardware) : base(key, name, hardware)

View file

@ -6,6 +6,7 @@ using Crestron.SimplSharp;
using Crestron.SimplSharpPro; using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport; using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters; using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using Crestron.SimplSharpPro.DM;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
@ -18,7 +19,7 @@ namespace PepperDash.Essentials.DM
/// Controller class for suitable for HDBaseT transmitters /// Controller class for suitable for HDBaseT transmitters
/// </summary> /// </summary>
[Description("Wrapper Class for HDBaseT devices based on HDTx3CB class")] [Description("Wrapper Class for HDBaseT devices based on HDTx3CB class")]
public class HDBaseTTxController: BasicDmTxControllerBase, IRoutingInputsOutputs, IComPorts public class HDBaseTTxController : BasicDmTxControllerBase, IRoutingInputsOutputs, IComPorts
{ {
public RoutingInputPort HdmiIn { get; private set; } public RoutingInputPort HdmiIn { get; private set; }
public RoutingOutputPort DmOut { get; private set; } public RoutingOutputPort DmOut { get; private set; }
@ -26,6 +27,8 @@ namespace PepperDash.Essentials.DM
public HDBaseTTxController(string key, string name, HDTx3CB tx) public HDBaseTTxController(string key, string name, HDTx3CB tx)
: base(key, name, tx) : base(key, name, tx)
{ {
PreventRegistration = true;
HdmiIn = new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video, HdmiIn = new RoutingInputPort(DmPortName.HdmiIn1, eRoutingSignalType.Audio | eRoutingSignalType.Video,
eRoutingPortConnectionType.Hdmi, null, this) { Port = tx }; eRoutingPortConnectionType.Hdmi, null, this) { Port = tx };
@ -34,6 +37,21 @@ namespace PepperDash.Essentials.DM
InputPorts = new RoutingPortCollection<RoutingInputPort> { HdmiIn }; InputPorts = new RoutingPortCollection<RoutingInputPort> { HdmiIn };
OutputPorts = new RoutingPortCollection<RoutingOutputPort> { DmOut }; OutputPorts = new RoutingPortCollection<RoutingOutputPort> { DmOut };
var parentDev = DeviceManager.GetDeviceForKey(key);
var num = tx.DMInputOutput.Number;
if (parentDev is DmpsRoutingController)
{
var dmps = parentDev as DmpsRoutingController;
IsOnline.SetValueFunc(() => dmps.InputEndpointOnlineFeedbacks[num].BoolValue);
dmps.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
else if (parentDev is DmChassisController)
{
var controller = parentDev as DmChassisController;
IsOnline.SetValueFunc(() => controller.InputEndpointOnlineFeedbacks[num].BoolValue);
controller.InputEndpointOnlineFeedbacks[num].OutputChange += (o, a) => IsOnline.FireUpdate();
}
} }
#region IRoutingInputs Members #region IRoutingInputs Members
@ -79,7 +97,7 @@ namespace PepperDash.Essentials.DM
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X")); Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]); this.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = this.Name;
} }
#endregion #endregion
@ -101,6 +119,10 @@ namespace PepperDash.Essentials.DM
JoinType = eJoinType.Digital JoinType = eJoinType.Digital
}); });
[JoinName("Name")]
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
new JoinMetadata { Description = "DM Tx Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
/// <summary> /// <summary>
/// Plugin device BridgeJoinMap constructor /// Plugin device BridgeJoinMap constructor
/// </summary> /// </summary>

View file

@ -93,6 +93,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="AirMedia\AirMediaPropertiesConfig.cs" /> <Compile Include="AirMedia\AirMediaPropertiesConfig.cs" />
<Compile Include="AirMedia\AirMediaController.cs" /> <Compile Include="AirMedia\AirMediaController.cs" />
<Compile Include="Chassis\DmpsDigitalOutputController.cs" />
<Compile Include="Chassis\DmpsMicrophoneController.cs" /> <Compile Include="Chassis\DmpsMicrophoneController.cs" />
<Compile Include="Chassis\DmBladeChassisController.cs" /> <Compile Include="Chassis\DmBladeChassisController.cs" />
<Compile Include="Chassis\DmCardAudioOutput.cs" /> <Compile Include="Chassis\DmCardAudioOutput.cs" />
@ -100,6 +101,7 @@
<Compile Include="Chassis\DmpsAudioOutputController.cs" /> <Compile Include="Chassis\DmpsAudioOutputController.cs" />
<Compile Include="Chassis\DmpsInternalVirtualDmTxController.cs" /> <Compile Include="Chassis\DmpsInternalVirtualDmTxController.cs" />
<Compile Include="Chassis\DmpsRoutingController.cs" /> <Compile Include="Chassis\DmpsRoutingController.cs" />
<Compile Include="Chassis\HdMd8xNController.cs" />
<Compile Include="Chassis\HdMdNxM4kEBridgeableController.cs" /> <Compile Include="Chassis\HdMdNxM4kEBridgeableController.cs" />
<Compile Include="Chassis\HdMdNxM4kEController.cs" /> <Compile Include="Chassis\HdMdNxM4kEController.cs" />
<Compile Include="Config\InputPropertiesConfig.cs" /> <Compile Include="Config\InputPropertiesConfig.cs" />

View file

@ -308,7 +308,7 @@ namespace PepperDash.Essentials.Devices.Displays
//Send((string)selector); //Send((string)selector);
} }
void SetVolume(ushort level) public void SetVolume(ushort level)
{ {
var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level); var levelString = string.Format("{0}{1:X4}\x03", VolumeLevelPartialCmd, level);
AppendChecksumAndSend(levelString); AppendChecksumAndSend(levelString);
@ -333,10 +333,13 @@ namespace PepperDash.Essentials.Devices.Displays
Send(MuteOnCmd); Send(MuteOnCmd);
} }
void IBasicVolumeWithFeedback.SetVolume(ushort level)
/*
public void IBasicVolumeWithFeedback.SetVolume(ushort level)
{ {
SetVolume(level); SetVolume(level);
} }
*/
#endregion #endregion

View file

@ -290,7 +290,7 @@ namespace PepperDash.Essentials.Devices.Displays
//Send((string)selector); //Send((string)selector);
} }
void SetVolume(ushort level) public void SetVolume(ushort level)
{ {
var levelString = string.Format("{0}{1:X3}\x03", VolumeLevelPartialCmd, level); var levelString = string.Format("{0}{1:X3}\x03", VolumeLevelPartialCmd, level);
@ -315,11 +315,12 @@ namespace PepperDash.Essentials.Devices.Displays
Send(MuteOnCmd); Send(MuteOnCmd);
} }
/*
void IBasicVolumeWithFeedback.SetVolume(ushort level) void IBasicVolumeWithFeedback.SetVolume(ushort level)
{ {
SetVolume(level); SetVolume(level);
} }
*/
#endregion #endregion
#region IBasicVolumeControls Members #region IBasicVolumeControls Members

View file

@ -108,6 +108,7 @@
<Compile Include="Codec\eCodecCallStatus.cs" /> <Compile Include="Codec\eCodecCallStatus.cs" />
<Compile Include="Codec\eMeetingPrivacy.cs" /> <Compile Include="Codec\eMeetingPrivacy.cs" />
<Compile Include="Codec\iCodecAudio.cs" /> <Compile Include="Codec\iCodecAudio.cs" />
<Compile Include="VideoCodec\IConvertiblePreset.cs" />
<Compile Include="Codec\IHasCallHold.cs" /> <Compile Include="Codec\IHasCallHold.cs" />
<Compile Include="Codec\IHasDoNotDisturb.cs" /> <Compile Include="Codec\IHasDoNotDisturb.cs" />
<Compile Include="Codec\IHasExternalSourceSwitching.cs" /> <Compile Include="Codec\IHasExternalSourceSwitching.cs" />

View file

@ -1023,20 +1023,25 @@ ConnectorID: {2}"
if (tempPresets.Count > 0) if (tempPresets.Count > 0)
{ {
// Create temporary list to store the existing items from the CiscoCodecStatus.RoomPreset collection // Create temporary list to store the existing items from the CiscoCodecStatus.RoomPreset collection
List<CiscoCodecStatus.RoomPreset> existingRoomPresets = new List<CiscoCodecStatus.RoomPreset>(); var existingRoomPresets = new List<IConvertiblePreset>();
// Add the existing items to the temporary list // Add the existing items to the temporary list
existingRoomPresets.AddRange(CodecStatus.Status.RoomPreset); existingRoomPresets.AddRange(CodecStatus.Status.RoomPreset);
// Populate the CodecStatus object (this will append new values to the RoomPreset collection // Populate the CodecStatus object (this will append new values to the RoomPreset collection
JsonConvert.PopulateObject(response, CodecStatus); JsonConvert.PopulateObject(response, CodecStatus);
JObject jResponse = JObject.Parse(response); var jResponse = JObject.Parse(response);
List<CiscoCodecStatus.RoomPreset> convertedRoomPresets =
existingRoomPresets.Select(a => (CiscoCodecStatus.RoomPreset) a).ToList();
IList<JToken> roomPresets = jResponse["Status"]["RoomPreset"].Children().ToList(); IList<JToken> roomPresets = jResponse["Status"]["RoomPreset"].Children().ToList();
// Iterate the new items in this response agains the temporary list. Overwrite any existing items and add new ones. // Iterate the new items in this response agains the temporary list. Overwrite any existing items and add new ones.
foreach (var preset in tempPresets) foreach (var camPreset in tempPresets)
{ {
var preset = camPreset as CiscoCodecStatus.RoomPreset;
if (preset == null) continue;
// First fine the existing preset that matches the id // First fine the existing preset that matches the id
var existingPreset = existingRoomPresets.FirstOrDefault(p => p.id.Equals(preset.id)); var existingPreset = convertedRoomPresets.FirstOrDefault(p => p.id.Equals(preset.id));
if (existingPreset != null) if (existingPreset != null)
{ {
Debug.Console(1, this, "Existing Room Preset with ID: {0} found. Updating.", existingPreset.id); Debug.Console(1, this, "Existing Room Preset with ID: {0} found. Updating.", existingPreset.id);
@ -1068,7 +1073,7 @@ ConnectorID: {2}"
CodecStatus.Status.RoomPreset = existingRoomPresets; CodecStatus.Status.RoomPreset = existingRoomPresets;
// Generecise the list // Generecise the list
NearEndPresets = RoomPresets.GetGenericPresets(CodecStatus.Status.RoomPreset); NearEndPresets = existingRoomPresets.GetGenericPresets<CodecRoomPreset>();
var handler = CodecRoomPresetsListHasChanged; var handler = CodecRoomPresetsListHasChanged;
if (handler != null) if (handler != null)
@ -2465,20 +2470,6 @@ ConnectorID: {2}"
} }
/// <summary>
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
/// </summary>
public class CodecCommandWithLabel
{
public string Command { get; set; }
public string Label { get; set; }
public CodecCommandWithLabel(string command, string label)
{
Command = command;
Label = label;
}
}
/// <summary> /// <summary>
/// Tracks the initial sycnronization state of the codec when making a connection /// Tracks the initial sycnronization state of the codec when making a connection

View file

@ -1,14 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Core.Presets; using PepperDash.Essentials.Core.Presets;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
namespace PepperDash.Essentials.Devices.Common.VideoCodec namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
@ -33,39 +28,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
public static class RoomPresets public static class RoomPresets
{ {
/// <summary> /// <summary>
/// Converts Cisco RoomPresets to generic CameraPresets /// Converts non-generic RoomPresets to generic CameraPresets
/// </summary> /// </summary>
/// <param name="presets"></param> /// <param name="presets"></param>
/// <returns></returns> /// <returns></returns>
public static List<CodecRoomPreset> GetGenericPresets(List<CiscoCodecStatus.RoomPreset> presets) public static List<T> GetGenericPresets<T>(this List<IConvertiblePreset> presets)
{ {
var cameraPresets = new List<CodecRoomPreset>(); return
presets.Select(preset => preset.ConvertCodecPreset())
if (Debug.Level > 0) .Where(newPreset => newPreset != null)
{ .Cast<T>()
Debug.Console(1, "Presets List:"); .ToList();
}
foreach (CiscoCodecStatus.RoomPreset preset in presets)
{
try
{
var cameraPreset = new CodecRoomPreset(UInt16.Parse(preset.id), preset.Description.Value, preset.Defined.BoolValue, true);
cameraPresets.Add(cameraPreset);
if (Debug.Level > 0)
{
Debug.Console(1, "Added Preset ID: {0}, Description: {1}, IsDefined: {2}, isDefinable: {3}", cameraPreset.ID, cameraPreset.Description, cameraPreset.Defined, cameraPreset.IsDefinable);
}
}
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", preset.id, e);
}
}
return cameraPresets;
} }
} }

View file

@ -9,6 +9,7 @@ using Newtonsoft.Json.Linq;
using PepperDash.Core; using PepperDash.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec; using PepperDash.Essentials.Devices.Common.VideoCodec.CiscoCodec;
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
{ {
@ -2185,7 +2186,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
} }
} }
public class RoomPreset public class RoomPreset : IConvertiblePreset
{ {
public string id { get; set; } public string id { get; set; }
public Defined Defined { get; set; } public Defined Defined { get; set; }
@ -2198,7 +2199,24 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Description = new Description2(); Description = new Description2();
Type = new Type5(); Type = new Type5();
} }
public PresetBase ConvertCodecPreset()
{
try
{
var preset = new CodecRoomPreset(UInt16.Parse(id), Description.Value, Defined.BoolValue, true);
Debug.Console(2, "Preset ID {0} Converted from Cisco Codec Preset to Essentials Preset");
return preset;
} }
catch (Exception e)
{
Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", id, e);
return null;
}
}
}
@ -2222,7 +2240,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
public Proximity Proximity { get; set; } public Proximity Proximity { get; set; }
public RoomAnalytics RoomAnalytics { get; set; } public RoomAnalytics RoomAnalytics { get; set; }
public List<RoomPreset> RoomPreset { get; set; } public List<IConvertiblePreset> RoomPreset { get; set; }
public SIP SIP { get; set; } public SIP SIP { get; set; }
public Security Security { get; set; } public Security Security { get; set; }
@ -2239,7 +2257,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
Standby = new Standby(); Standby = new Standby();
Cameras = new Cameras(); Cameras = new Cameras();
RoomAnalytics = new RoomAnalytics(); RoomAnalytics = new RoomAnalytics();
RoomPreset = new List<RoomPreset>(); RoomPreset = new List<IConvertiblePreset>();
Conference = new Conference2(); Conference = new Conference2();
SystemUnit = new SystemUnit(); SystemUnit = new SystemUnit();
Video = new Video(); Video = new Video();

View file

@ -0,0 +1,9 @@
using PepperDash.Essentials.Core.Presets;
namespace PepperDash.Essentials.Devices.Common.VideoCodec
{
public interface IConvertiblePreset
{
PresetBase ConvertCodecPreset();
}
}

View file

@ -22,6 +22,26 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
void MinMaxLayoutToggle(); void MinMaxLayoutToggle();
} }
/// <summary>
/// Defines the required elements for layout control with direct layout selection
/// </summary>
public interface IHasCodecLayoutsAvailable : IHasCodecLayouts
{
event EventHandler<AvailableLayoutChangedEventArgs> AvailableLayoutsChanged;
StringFeedback AvailableLocalLayoutsFeedback { get; }
List<CodecCommandWithLabel> AvailableLocalLayouts { get; }
void LocalLayoutSet(string layout);
void LocalLayoutSet(CodecCommandWithLabel layout);
}
public class AvailableLayoutChangedEventArgs : EventArgs
{
public List<CodecCommandWithLabel> AvailableLayouts { get; set; }
}
/// <summary> /// <summary>
/// Defines the requirements for Zoom Room layout control /// Defines the requirements for Zoom Room layout control
/// </summary> /// </summary>

View file

@ -1,5 +1,5 @@
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core;
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{ {

View file

@ -1,4 +1,4 @@
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; using PepperDash.Essentials.Devices.Common.VideoCodec;
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
{ {

View file

@ -371,6 +371,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap); LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
} }
if (codec is IHasCodecLayoutsAvailable)
{
LinkVideoCodecAvailableLayoutsToApi(codec as IHasCodecLayoutsAvailable, trilist, joinMap);
}
if (codec is IHasSelfviewPosition) if (codec is IHasSelfviewPosition)
{ {
LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap); LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
@ -458,10 +463,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
} }
SharingContentIsOnFeedback.FireUpdate(); SharingContentIsOnFeedback.FireUpdate();
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
}; };
} }
@ -1037,9 +1038,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
if (!args.DeviceOnLine) return; if (!args.DeviceOnLine) return;
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, "\xFC"); var clearBytes = XSigHelpers.ClearOutputs();
UpdateDirectoryXSig(codec.CurrentDirectoryResult, trilist.SetString(joinMap.DirectoryEntries.JoinNumber,
codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false); Encoding.GetEncoding(XSigEncoding).GetString(clearBytes, 0, clearBytes.Length));
var directoryXSig = UpdateDirectoryXSig(codec.DirectoryRoot, codec.CurrentDirectoryResultIsNotDirectoryRoot.BoolValue == false);
trilist.SetString(joinMap.DirectoryEntries.JoinNumber, directoryXSig);
}; };
} }
@ -1359,9 +1362,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
{ {
if (!args.DeviceOnLine) return; if (!args.DeviceOnLine) return;
// TODO [ ] Issue #868 // TODO [ ] #983
Debug.Console(0, this, "LinkVideoCodecCallControlsToApi: device is {0}, IsInCall {1}", args.DeviceOnLine ? "online" : "offline", IsInCall);
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC"); trilist.SetString(joinMap.CurrentCallData.JoinNumber, "\xFC");
UpdateCallStatusXSig(); trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
}; };
} }
@ -1484,6 +1489,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentLayoutStringFb.JoinNumber]); codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentLayoutStringFb.JoinNumber]);
} }
private void LinkVideoCodecAvailableLayoutsToApi(IHasCodecLayoutsAvailable codec, BasicTriList trilist,
VideoCodecControllerJoinMap joinMap)
{
codec.AvailableLocalLayoutsFeedback.LinkInputSig(trilist.StringInput[joinMap.AvailableLayoutsFb.JoinNumber]);
trilist.SetStringSigAction(joinMap.SelectLayout.JoinNumber, codec.LocalLayoutSet);
}
private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap) private void LinkVideoCodecCameraModeToApi(IHasCameraAutoMode codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
{ {
trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn); trilist.SetSigFalseAction(joinMap.CameraModeAuto.JoinNumber, codec.CameraAutoModeOn);
@ -1995,4 +2008,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
} }
} }
} }
/// <summary>
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
/// </summary>
public class CodecCommandWithLabel
{
public string Command { get; private set; }
public string Label { get; private set; }
public CodecCommandWithLabel(string command, string label)
{
Command = command;
Label = label;
}
}
} }