mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-15 12:44:58 +00:00
Merge pull request #366 from PepperDash/feature/cisco-external-sources
Add External Source API to VideoCodec
This commit is contained in:
@@ -2,340 +2,340 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
using Crestron.SimplSharpPro.Fusion;
|
using Crestron.SimplSharpPro.Fusion;
|
||||||
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.Fusion;
|
using PepperDash.Essentials.Core.Fusion;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Fusion
|
namespace PepperDash.Essentials.Fusion
|
||||||
{
|
{
|
||||||
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||||
{
|
{
|
||||||
BooleanSigData CodecIsInCall;
|
BooleanSigData CodecIsInCall;
|
||||||
|
|
||||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
||||||
: base(room, ipId)
|
: base(room, ipId)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called in base class constructor before RVI and GUID files are built
|
/// Called in base class constructor before RVI and GUID files are built
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void ExecuteCustomSteps()
|
protected override void ExecuteCustomSteps()
|
||||||
{
|
{
|
||||||
SetUpCodec();
|
SetUpCodec();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
/// Creates a static asset for the codec and maps the joins to the main room symbol
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetUpCodec()
|
void SetUpCodec()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||||
|
|
||||||
if (codec == null)
|
if (codec == null)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
|
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec.UsageTracker = new UsageTracking(codec);
|
codec.UsageTracker = new UsageTracking(codec);
|
||||||
codec.UsageTracker.UsageIsTracked = true;
|
codec.UsageTracker.UsageIsTracked = true;
|
||||||
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||||
|
|
||||||
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
|
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); });
|
||||||
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
|
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
|
||||||
|
|
||||||
// Map FusionRoom Attributes:
|
// Map FusionRoom Attributes:
|
||||||
|
|
||||||
// Codec volume
|
// Codec volume
|
||||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
|
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
|
||||||
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||||
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
||||||
|
|
||||||
// In Call Status
|
// In Call Status
|
||||||
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
||||||
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
||||||
|
|
||||||
// Online status
|
// Online status
|
||||||
if (codec is ICommunicationMonitor)
|
if (codec is ICommunicationMonitor)
|
||||||
{
|
{
|
||||||
var c = codec as ICommunicationMonitor;
|
var c = codec as ICommunicationMonitor;
|
||||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
|
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
|
||||||
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||||
c.CommunicationMonitor.StatusChange += (o, a) =>
|
c.CommunicationMonitor.StatusChange += (o, a) =>
|
||||||
{
|
{
|
||||||
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
||||||
};
|
};
|
||||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
|
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Codec IP Address
|
// Codec IP Address
|
||||||
bool codecHasIpInfo = false;
|
bool codecHasIpInfo = false;
|
||||||
var codecComm = codec.Communication;
|
var codecComm = codec.Communication;
|
||||||
|
|
||||||
string codecIpAddress = string.Empty;
|
string codecIpAddress = string.Empty;
|
||||||
int codecIpPort = 0;
|
int codecIpPort = 0;
|
||||||
|
|
||||||
StringSigData codecIpAddressSig;
|
StringSigData codecIpAddressSig;
|
||||||
StringSigData codecIpPortSig;
|
StringSigData codecIpPortSig;
|
||||||
|
|
||||||
if(codecComm is GenericSshClient)
|
if(codecComm is GenericSshClient)
|
||||||
{
|
{
|
||||||
codecIpAddress = (codecComm as GenericSshClient).Hostname;
|
codecIpAddress = (codecComm as GenericSshClient).Hostname;
|
||||||
codecIpPort = (codecComm as GenericSshClient).Port;
|
codecIpPort = (codecComm as GenericSshClient).Port;
|
||||||
codecHasIpInfo = true;
|
codecHasIpInfo = true;
|
||||||
}
|
}
|
||||||
else if (codecComm is GenericTcpIpClient)
|
else if (codecComm is GenericTcpIpClient)
|
||||||
{
|
{
|
||||||
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
|
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
|
||||||
codecIpPort = (codecComm as GenericTcpIpClient).Port;
|
codecIpPort = (codecComm as GenericTcpIpClient).Port;
|
||||||
codecHasIpInfo = true;
|
codecHasIpInfo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codecHasIpInfo)
|
if (codecHasIpInfo)
|
||||||
{
|
{
|
||||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
|
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
|
||||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||||
|
|
||||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
|
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
|
||||||
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempAsset = new FusionAsset();
|
var tempAsset = new FusionAsset();
|
||||||
|
|
||||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
|
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
|
||||||
|
|
||||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||||
{
|
{
|
||||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create a new asset
|
// Create a new asset
|
||||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
|
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", "");
|
||||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||||
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||||
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||||
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||||
|
|
||||||
// TODO: Map relevant attributes on asset symbol
|
// TODO: Map relevant attributes on asset symbol
|
||||||
|
|
||||||
codecAsset.TrySetMakeModel(codec);
|
codecAsset.TrySetMakeModel(codec);
|
||||||
codecAsset.TryLinkAssetErrorToCommunication(codec);
|
codecAsset.TryLinkAssetErrorToCommunication(codec);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
|
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e)
|
||||||
{
|
{
|
||||||
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec;
|
||||||
|
|
||||||
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
CodecIsInCall.InputSig.BoolValue = codec.IsInCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These methods are overridden because they access the room class which is of a different type
|
// These methods are overridden because they access the room class which is of a different type
|
||||||
|
|
||||||
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
protected override void CreateSymbolAndBasicSigs(uint ipId)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
|
||||||
|
|
||||||
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
|
||||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
|
||||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
|
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
|
||||||
|
|
||||||
FusionRoom.Register();
|
FusionRoom.Register();
|
||||||
|
|
||||||
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
|
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
|
||||||
|
|
||||||
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
|
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange;
|
||||||
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
|
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
|
||||||
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
|
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
|
||||||
|
|
||||||
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
// Room to fusion room
|
// Room to fusion room
|
||||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||||
|
|
||||||
// Moved to
|
// Moved to
|
||||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
|
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
|
||||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||||
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||||
|
|
||||||
|
|
||||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||||
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
|
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
|
||||||
|
|
||||||
|
|
||||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SetUpSources()
|
protected override void SetUpSources()
|
||||||
{
|
{
|
||||||
// Sources
|
// Sources
|
||||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey);
|
||||||
if (dict != null)
|
if (dict != null)
|
||||||
{
|
{
|
||||||
// NEW PROCESS:
|
// NEW PROCESS:
|
||||||
// Make these lists and insert the fusion attributes by iterating these
|
// Make these lists and insert the fusion attributes by iterating these
|
||||||
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
|
||||||
uint i = 1;
|
uint i = 1;
|
||||||
foreach (var kvp in setTopBoxes)
|
foreach (var kvp in setTopBoxes)
|
||||||
{
|
{
|
||||||
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
|
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
i++;
|
i++;
|
||||||
if (i > 5) // We only have five spots
|
if (i > 5) // We only have five spots
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
|
||||||
i = 1;
|
i = 1;
|
||||||
foreach (var kvp in discPlayers)
|
foreach (var kvp in discPlayers)
|
||||||
{
|
{
|
||||||
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
|
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
i++;
|
i++;
|
||||||
if (i > 5) // We only have five spots
|
if (i > 5) // We only have five spots
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
|
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
|
||||||
i = 1;
|
i = 1;
|
||||||
foreach (var kvp in laptops)
|
foreach (var kvp in laptops)
|
||||||
{
|
{
|
||||||
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||||
i++;
|
i++;
|
||||||
if (i > 10) // We only have ten spots???
|
if (i > 10) // We only have ten spots???
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var kvp in dict)
|
foreach (var kvp in dict)
|
||||||
{
|
{
|
||||||
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
|
var usageDevice = kvp.Value.SourceDevice as IUsageTracking;
|
||||||
|
|
||||||
if (usageDevice != null)
|
if (usageDevice != null)
|
||||||
{
|
{
|
||||||
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
|
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device);
|
||||||
usageDevice.UsageTracker.UsageIsTracked = true;
|
usageDevice.UsageTracker.UsageIsTracked = true;
|
||||||
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
|
||||||
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void SetUpDisplay()
|
protected override void SetUpDisplay()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//Setup Display Usage Monitoring
|
//Setup Display Usage Monitoring
|
||||||
|
|
||||||
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
|
||||||
|
|
||||||
// Consider updating this in multiple display systems
|
// Consider updating this in multiple display systems
|
||||||
|
|
||||||
foreach (DisplayBase display in displays)
|
foreach (DisplayBase display in displays)
|
||||||
{
|
{
|
||||||
display.UsageTracker = new UsageTracking(display);
|
display.UsageTracker = new UsageTracking(display);
|
||||||
display.UsageTracker.UsageIsTracked = true;
|
display.UsageTracker.UsageIsTracked = true;
|
||||||
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded);
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase;
|
||||||
if (defaultDisplay == null)
|
if (defaultDisplay == null)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
|
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); });
|
||||||
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
|
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); });
|
||||||
|
|
||||||
// Display to fusion room sigs
|
// Display to fusion room sigs
|
||||||
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||||
if (defaultDisplay is IDisplayUsage)
|
if (defaultDisplay is IDisplayUsage)
|
||||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
||||||
|
|
||||||
|
|
||||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||||
|
|
||||||
//Check for existing asset in GUIDs collection
|
//Check for existing asset in GUIDs collection
|
||||||
|
|
||||||
var tempAsset = new FusionAsset();
|
var tempAsset = new FusionAsset();
|
||||||
|
|
||||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||||
{
|
{
|
||||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create a new asset
|
// Create a new asset
|
||||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
|
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", "");
|
||||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||||
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
||||||
// Use extension methods
|
// Use extension methods
|
||||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
|
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
|
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
|
||||||
{
|
{
|
||||||
string displayName = string.Format("Display {0} - ", displayIndex);
|
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||||
|
|
||||||
|
|
||||||
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
|
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay)
|
||||||
{
|
{
|
||||||
// Power on
|
// Power on
|
||||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||||
|
|
||||||
// Power Off
|
// Power Off
|
||||||
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
|
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
|
||||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
|
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
|
||||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||||
|
|
||||||
// Current Source
|
// Current Source
|
||||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||||
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
|
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey); }); ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,6 +50,19 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
//************************
|
//************************
|
||||||
|
|
||||||
|
public override string SourceListKey
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _SourceListKey;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_SourceListKey = value;
|
||||||
|
SetCodecExternalSources();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override Func<bool> OnFeedbackFunc
|
protected override Func<bool> OnFeedbackFunc
|
||||||
{
|
{
|
||||||
@@ -206,9 +219,11 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
VideoCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.VideoCodecKey) as
|
||||||
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
PepperDash.Essentials.Devices.Common.VideoCodec.VideoCodecBase;
|
||||||
|
|
||||||
|
|
||||||
if (VideoCodec == null)
|
if (VideoCodec == null)
|
||||||
throw new ArgumentNullException("codec cannot be null");
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
|
||||||
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
AudioCodec = DeviceManager.GetDeviceForKey(PropertiesConfig.AudioCodecKey) as
|
||||||
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
PepperDash.Essentials.Devices.Common.AudioCodec.AudioCodecBase;
|
||||||
if (AudioCodec == null)
|
if (AudioCodec == null)
|
||||||
@@ -298,6 +313,7 @@ namespace PepperDash.Essentials
|
|||||||
|
|
||||||
|
|
||||||
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
|
VideoCodec.IsReadyChange += (o, a) => this.SetCodecExternalSources();
|
||||||
|
|
||||||
if (AudioCodec != null)
|
if (AudioCodec != null)
|
||||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||||
@@ -346,11 +362,10 @@ namespace PepperDash.Essentials
|
|||||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||||
|
|
||||||
return base.CustomActivate();
|
return base.CustomActivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -672,6 +687,42 @@ namespace PepperDash.Essentials
|
|||||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||||
|
/// </summary>
|
||||||
|
private void SetCodecExternalSources()
|
||||||
|
{
|
||||||
|
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||||
|
|
||||||
|
if (videoCodecWithExternalSwitching == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string codecTieLine = "";
|
||||||
|
codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort;
|
||||||
|
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||||
|
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
|
||||||
|
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||||
|
|
||||||
|
foreach (var kvp in srcList)
|
||||||
|
{
|
||||||
|
var srcConfig = kvp.Value;
|
||||||
|
|
||||||
|
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||||
|
{
|
||||||
|
|
||||||
|
videoCodecWithExternalSwitching.AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||||
|
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region IPrivacy Members
|
#region IPrivacy Members
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1047,12 +1047,15 @@ namespace PepperDash.Essentials
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void SetupSourceList()
|
void SetupSourceList()
|
||||||
{
|
{
|
||||||
|
|
||||||
var inCall = CurrentRoom.InCallFeedback.BoolValue;
|
var inCall = CurrentRoom.InCallFeedback.BoolValue;
|
||||||
var config = ConfigReader.ConfigObject.SourceLists;
|
var config = ConfigReader.ConfigObject.SourceLists;
|
||||||
|
|
||||||
|
|
||||||
if (config.ContainsKey(_CurrentRoom.SourceListKey))
|
if (config.ContainsKey(_CurrentRoom.SourceListKey))
|
||||||
{
|
{
|
||||||
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
|
var srcList = config[_CurrentRoom.SourceListKey].OrderBy(kv => kv.Value.Order);
|
||||||
|
|
||||||
|
|
||||||
// Setup sources list
|
// Setup sources list
|
||||||
SourceStagingSrl.Clear();
|
SourceStagingSrl.Clear();
|
||||||
@@ -1076,6 +1079,8 @@ namespace PepperDash.Essentials
|
|||||||
b => { if (!b) UiSelectSource(routeKey); });
|
b => { if (!b) UiSelectSource(routeKey); });
|
||||||
SourceStagingSrl.AddItem(item); // add to the SRL
|
SourceStagingSrl.AddItem(item); // add to the SRL
|
||||||
item.RegisterForSourceChange(_CurrentRoom);
|
item.RegisterForSourceChange(_CurrentRoom);
|
||||||
|
Debug.Console(1, "**** KEY {0}", kvp.Key);
|
||||||
|
|
||||||
}
|
}
|
||||||
SourceStagingSrl.Count = (ushort)(i - 1);
|
SourceStagingSrl.Count = (ushort)(i - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
using Crestron.SimplSharpPro;
|
using Crestron.SimplSharpPro;
|
||||||
using Crestron.SimplSharpPro.DeviceSupport;
|
using Crestron.SimplSharpPro.DeviceSupport;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
|
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Core
|
namespace PepperDash.Essentials.Core
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IR port wrapper. May act standalone
|
/// IR port wrapper. May act standalone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IrOutputPortController : Device
|
public class IrOutputPortController : Device
|
||||||
{
|
{
|
||||||
uint IrPortUid;
|
uint IrPortUid;
|
||||||
IROutputPort IrPort;
|
IROutputPort IrPort;
|
||||||
|
|
||||||
public ushort StandardIrPulseTime { get; set; }
|
public ushort StandardIrPulseTime { get; set; }
|
||||||
public string DriverFilepath { get; private set; }
|
public string DriverFilepath { get; private set; }
|
||||||
public bool DriverIsLoaded { get; private set; }
|
public bool DriverIsLoaded { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor for IrDevice base class. If a null port is provided, this class will
|
/// Constructor for IrDevice base class. If a null port is provided, this class will
|
||||||
/// still function without trying to talk to a port.
|
/// still function without trying to talk to a port.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath)
|
public IrOutputPortController(string key, IROutputPort port, string irDriverFilepath)
|
||||||
: base(key)
|
: base(key)
|
||||||
{
|
{
|
||||||
//if (port == null) throw new ArgumentNullException("port");
|
//if (port == null) throw new ArgumentNullException("port");
|
||||||
IrPort = port;
|
IrPort = port;
|
||||||
if (port == null)
|
if (port == null)
|
||||||
{
|
{
|
||||||
Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function");
|
Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LoadDriver(irDriverFilepath);
|
LoadDriver(irDriverFilepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IrOutputPortController(string key, Func<DeviceConfig, IROutputPort> postActivationFunc,
|
public IrOutputPortController(string key, Func<DeviceConfig, IROutputPort> postActivationFunc,
|
||||||
@@ -54,85 +54,85 @@ namespace PepperDash.Essentials.Core
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the IR driver at path
|
/// Loads the IR driver at path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path"></param>
|
/// <param name="path"></param>
|
||||||
public void LoadDriver(string path)
|
public void LoadDriver(string path)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(path)) path = DriverFilepath;
|
if (string.IsNullOrEmpty(path)) path = DriverFilepath;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IrPortUid = IrPort.LoadIRDriver(path);
|
IrPortUid = IrPort.LoadIRDriver(path);
|
||||||
DriverFilepath = path;
|
DriverFilepath = path;
|
||||||
StandardIrPulseTime = 200;
|
StandardIrPulseTime = 200;
|
||||||
DriverIsLoaded = true;
|
DriverIsLoaded = true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
DriverIsLoaded = false;
|
DriverIsLoaded = false;
|
||||||
var message = string.Format("WARNING IR Driver '{0}' failed to load", path);
|
var message = string.Format("WARNING IR Driver '{0}' failed to load", path);
|
||||||
Debug.Console(0, this, message);
|
Debug.Console(0, this, message);
|
||||||
ErrorLog.Error(message);
|
ErrorLog.Error(message);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Starts and stops IR command on driver. Safe for missing commands
|
|
||||||
/// </summary>
|
|
||||||
public virtual void PressRelease(string command, bool state)
|
|
||||||
{
|
|
||||||
Debug.Console(2, this, "IR:'{0}'={1}", command, state);
|
|
||||||
if (IrPort == null)
|
|
||||||
{
|
|
||||||
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!DriverIsLoaded)
|
|
||||||
{
|
|
||||||
Debug.Console(2, this, "WARNING IR driver is not loaded");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state)
|
|
||||||
{
|
|
||||||
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
|
|
||||||
IrPort.Press(IrPortUid, command);
|
|
||||||
else
|
|
||||||
NoIrCommandError(command);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
IrPort.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Pulses a command on driver. Safe for missing commands
|
|
||||||
/// </summary>
|
|
||||||
public virtual void Pulse(string command, ushort time)
|
|
||||||
{
|
|
||||||
if (IrPort == null)
|
|
||||||
{
|
|
||||||
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!DriverIsLoaded)
|
|
||||||
{
|
|
||||||
Debug.Console(2, this, "WARNING IR driver is not loaded");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
|
|
||||||
IrPort.PressAndRelease(IrPortUid, command, time);
|
|
||||||
else
|
|
||||||
NoIrCommandError(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Notifies the console when a bad command is used.
|
|
||||||
/// </summary>
|
|
||||||
protected void NoIrCommandError(string command)
|
|
||||||
{
|
|
||||||
Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}",
|
|
||||||
Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts and stops IR command on driver. Safe for missing commands
|
||||||
|
/// </summary>
|
||||||
|
public virtual void PressRelease(string command, bool state)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "IR:'{0}'={1}", command, state);
|
||||||
|
if (IrPort == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!DriverIsLoaded)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING IR driver is not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
|
||||||
|
IrPort.Press(IrPortUid, command);
|
||||||
|
else
|
||||||
|
NoIrCommandError(command);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IrPort.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pulses a command on driver. Safe for missing commands
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Pulse(string command, ushort time)
|
||||||
|
{
|
||||||
|
if (IrPort == null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING No IR Port assigned to controller");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!DriverIsLoaded)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "WARNING IR driver is not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (IrPort.IsIRCommandAvailable(IrPortUid, command))
|
||||||
|
IrPort.PressAndRelease(IrPortUid, command, time);
|
||||||
|
else
|
||||||
|
NoIrCommandError(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Notifies the console when a bad command is used.
|
||||||
|
/// </summary>
|
||||||
|
protected void NoIrCommandError(string command)
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Device {0}: IR Driver {1} does not contain command {2}",
|
||||||
|
Key, IrPort.IRDriverFileNameByIRDriverId(IrPortUid), command);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,19 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The config name of the source list
|
/// The config name of the source list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SourceListKey { get; set; }
|
///
|
||||||
|
protected string _SourceListKey;
|
||||||
|
public virtual string SourceListKey {
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _SourceListKey;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_SourceListKey = value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Timer used for informing the UIs of a shutdown
|
/// Timer used for informing the UIs of a shutdown
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
|
{
|
||||||
|
public interface IHasExternalSourceSwitching
|
||||||
|
{
|
||||||
|
bool ExternalSourceListEnabled { get; }
|
||||||
|
void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type);
|
||||||
|
void SetExternalSourceState(string key, eExternalSourceMode mode);
|
||||||
|
void ClearExternalSources();
|
||||||
|
Action<string, string> RunRouteAction { set;}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -112,6 +112,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="Codec\IHasExternalSourceSwitching.cs" />
|
||||||
<Compile Include="ImageProcessors\TVOneCorio.cs" />
|
<Compile Include="ImageProcessors\TVOneCorio.cs" />
|
||||||
<Compile Include="ImageProcessors\TVOneCorioPropertiesConfig.cs" />
|
<Compile Include="ImageProcessors\TVOneCorioPropertiesConfig.cs" />
|
||||||
<Compile Include="Power Controllers\Digitallogger.cs" />
|
<Compile Include="Power Controllers\Digitallogger.cs" />
|
||||||
|
|||||||
@@ -15,16 +15,17 @@ using PepperDash.Essentials.Core.Config;
|
|||||||
using PepperDash.Essentials.Core.Routing;
|
using PepperDash.Essentials.Core.Routing;
|
||||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||||
using PepperDash.Essentials.Devices.Common.Codec;
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
using PepperDash.Essentials.Core;
|
|
||||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
||||||
{
|
{
|
||||||
enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration };
|
enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration };
|
||||||
|
public enum eExternalSourceType {camera, desktop, document_camera, mediaplayer, PC, whiteboard, other}
|
||||||
|
public enum eExternalSourceMode {Ready, NotReady, Hidden, Error}
|
||||||
|
|
||||||
public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory,
|
public class CiscoSparkCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory,
|
||||||
IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView,
|
IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfView,
|
||||||
ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets
|
ICommunicationMonitor, IRouting, IHasCodecCameras, IHasCameraAutoMode, IHasCodecRoomPresets, IHasExternalSourceSwitching
|
||||||
{
|
{
|
||||||
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
||||||
|
|
||||||
@@ -348,6 +349,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
|
|
||||||
CallHistory = new CodecCallHistory();
|
CallHistory = new CodecCallHistory();
|
||||||
|
|
||||||
|
|
||||||
if (props.Favorites != null)
|
if (props.Favorites != null)
|
||||||
{
|
{
|
||||||
CallFavorites = new CodecCallFavorites();
|
CallFavorites = new CodecCallFavorites();
|
||||||
@@ -398,6 +400,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
SetUpCameras();
|
SetUpCameras();
|
||||||
|
|
||||||
CreateOsdSource();
|
CreateOsdSource();
|
||||||
|
|
||||||
|
if (props.ExternalSourceListEnabled != null)
|
||||||
|
{
|
||||||
|
ExternalSourceListEnabled = props.ExternalSourceListEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -472,7 +479,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
prefix + "/Bookings" + Delimiter +
|
prefix + "/Bookings" + Delimiter +
|
||||||
prefix + "/Event/CallDisconnect" + Delimiter +
|
prefix + "/Event/CallDisconnect" + Delimiter +
|
||||||
prefix + "/Event/Bookings" + Delimiter +
|
prefix + "/Event/Bookings" + Delimiter +
|
||||||
prefix + "/Event/CameraPresetListUpdated" + Delimiter;
|
prefix + "/Event/CameraPresetListUpdated" + Delimiter +
|
||||||
|
prefix + "/Event/UserInterface/Presentation/ExternalSource/Selected/SourceIdentifier" + Delimiter;
|
||||||
|
|
||||||
return base.CustomActivate();
|
return base.CustomActivate();
|
||||||
}
|
}
|
||||||
@@ -629,6 +637,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,6 +862,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
{
|
{
|
||||||
GetBookings(null);
|
GetBookings(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (response.IndexOf("\"UserInterface\":{") > -1 || response.IndexOf("\"UserInterface\": {") > -1) // External Source Trigger
|
||||||
|
{
|
||||||
|
CiscoCodecEvents.RootObject eventReceived = new CiscoCodecEvents.RootObject();
|
||||||
|
JsonConvert.PopulateObject(response, eventReceived);
|
||||||
|
Debug.Console(2, this, "*** Got an External Source Selection {0} {1}", eventReceived, eventReceived.Event.UserInterface, eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value);
|
||||||
|
|
||||||
|
if (RunRouteAction != null)
|
||||||
|
{
|
||||||
|
RunRouteAction(eventReceived.Event.UserInterface.Presentation.ExternalSource.Selected.SourceIdentifier.Value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1)
|
else if (response.IndexOf("\"CommandResponse\":{") > -1 || response.IndexOf("\"CommandResponse\": {") > -1)
|
||||||
{
|
{
|
||||||
@@ -1802,9 +1823,76 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
SendText(string.Format("xCommand Call FarEndControl RoomPreset Activate CallId: {0} PresetId: {1}", GetCallId(), preset));
|
SendText(string.Format("xCommand Call FarEndControl RoomPreset Activate CallId: {0} PresetId: {1}", GetCallId(), preset));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
#region IHasExternalSourceSwitching Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Weather the Cisco supports External Source Lists or not
|
||||||
|
/// </summary>
|
||||||
|
public bool ExternalSourceListEnabled
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an external source to the Cisco
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connectorId"></param>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void AddExternalSource(string connectorId, string key, string name, eExternalSourceType type)
|
||||||
|
{
|
||||||
|
int id = 2;
|
||||||
|
if (connectorId.ToLower() == "hdmiin3")
|
||||||
|
{
|
||||||
|
id = 3;
|
||||||
|
}
|
||||||
|
SendText(string.Format("xCommand UserInterface Presentation ExternalSource Add ConnectorId: {0} SourceIdentifier: \"{1}\" Name: \"{2}\" Type: {3}", id, key, name, type.ToString()));
|
||||||
|
// SendText(string.Format("xCommand UserInterface Presentation ExternalSource State Set SourceIdentifier: \"{0}\" State: Ready", key));
|
||||||
|
Debug.Console(2, this, "Adding ExternalSource {0} {1}", connectorId, name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the state of the External Source
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="mode"></param>
|
||||||
|
public void SetExternalSourceState(string key, eExternalSourceMode mode)
|
||||||
|
{
|
||||||
|
SendText(string.Format("xCommand UserInterface Presentation ExternalSource State Set SourceIdentifier: \"{0}\" State: {1}", key, mode.ToString()));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Clears all external sources on the codec
|
||||||
|
/// </summary>
|
||||||
|
public void ClearExternalSources()
|
||||||
|
{
|
||||||
|
SendText("xCommand UserInterface Presentation ExternalSource RemoveAll");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Action that will run when the External Source is selected.
|
||||||
|
/// </summary>
|
||||||
|
public Action<string, string> RunRouteAction { private get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
#region ExternalDevices
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
|
/// Represents a codec command that might need to have a friendly label applied for UI feedback purposes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CodecCommandWithLabel
|
public class CodecCommandWithLabel
|
||||||
|
|||||||
@@ -1,47 +1,50 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Crestron.SimplSharp;
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.Codec
|
namespace PepperDash.Essentials.Devices.Common.Codec
|
||||||
{
|
{
|
||||||
public class CiscoSparkCodecPropertiesConfig
|
public class CiscoSparkCodecPropertiesConfig
|
||||||
{
|
{
|
||||||
[JsonProperty("communicationMonitorProperties")]
|
[JsonProperty("communicationMonitorProperties")]
|
||||||
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
public CommunicationMonitorConfig CommunicationMonitorProperties { get; set; }
|
||||||
|
|
||||||
[JsonProperty("favorites")]
|
[JsonProperty("favorites")]
|
||||||
public List<CodecActiveCallItem> Favorites { get; set; }
|
public List<CodecActiveCallItem> Favorites { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Valid values: "Local" or "Corporate"
|
/// Valid values: "Local" or "Corporate"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("phonebookMode")]
|
[JsonProperty("phonebookMode")]
|
||||||
public string PhonebookMode { get; set; }
|
public string PhonebookMode { get; set; }
|
||||||
|
|
||||||
[JsonProperty("showSelfViewByDefault")]
|
[JsonProperty("showSelfViewByDefault")]
|
||||||
public bool ShowSelfViewByDefault { get; set; }
|
public bool ShowSelfViewByDefault { get; set; }
|
||||||
|
|
||||||
[JsonProperty("sharing")]
|
[JsonProperty("sharing")]
|
||||||
public SharingProperties Sharing { get; set; }
|
public SharingProperties Sharing { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
[JsonProperty("externalSourceListEnabled")]
|
||||||
/// Optionsal property to set the limit of any phonebook queries for directory or searching
|
public bool ExternalSourceListEnabled { get; set; }
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("phonebookResultsLimit")]
|
/// <summary>
|
||||||
public uint PhonebookResultsLimit { get; set; }
|
/// Optionsal property to set the limit of any phonebook queries for directory or searching
|
||||||
|
/// </summary>
|
||||||
}
|
[JsonProperty("phonebookResultsLimit")]
|
||||||
|
public uint PhonebookResultsLimit { get; set; }
|
||||||
public class SharingProperties
|
|
||||||
{
|
}
|
||||||
[JsonProperty("autoShareContentWhileInCall")]
|
|
||||||
public bool AutoShareContentWhileInCall { get; set; }
|
public class SharingProperties
|
||||||
}
|
{
|
||||||
|
[JsonProperty("autoShareContentWhileInCall")]
|
||||||
|
public bool AutoShareContentWhileInCall { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -126,11 +126,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
public Encryption Encryption { get; set; }
|
public Encryption Encryption { get; set; }
|
||||||
public RequestedURI RequestedURI { get; set; }
|
public RequestedURI RequestedURI { get; set; }
|
||||||
public PeopleCountAverage PeopleCountAverage { get; set; }
|
public PeopleCountAverage PeopleCountAverage { get; set; }
|
||||||
}
|
}
|
||||||
|
public class UserInterface
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public Presentation Presentation { get; set; }
|
||||||
|
}
|
||||||
|
public class Presentation
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public ExternalSource ExternalSource { get; set; }
|
||||||
|
}
|
||||||
|
public class ExternalSource
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public Selected Selected { get; set; }
|
||||||
|
}
|
||||||
|
public class Selected
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public SourceIdentifier SourceIdentifier { get; set; }
|
||||||
|
}
|
||||||
|
public class SourceIdentifier
|
||||||
|
{
|
||||||
|
public string id { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
||||||
public class Event
|
public class Event
|
||||||
{
|
{
|
||||||
public CallDisconnect CallDisconnect { get; set; }
|
public CallDisconnect CallDisconnect { get; set; }
|
||||||
|
public UserInterface UserInterface { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RootObject
|
public class RootObject
|
||||||
|
|||||||
Reference in New Issue
Block a user