refactoring Fusion room classes

added DualDisplay Fusion support
This commit is contained in:
Andrew Welker
2020-07-02 15:11:07 -06:00
parent 153c7f2409
commit 6b8aa0afe6
4 changed files with 1641 additions and 1219 deletions

View File

@@ -1,341 +1,429 @@
using System; using System;
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.Essentials.Core;
using PepperDash.Core; using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Fusion;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.Core.Fusion; namespace PepperDash.Essentials.Fusion
{
namespace PepperDash.Essentials.Fusion public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
{ {
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase private BooleanSigData _codecIsInCall;
{
BooleanSigData CodecIsInCall; public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
: base(room, ipId)
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId) {
: base(room, ipId) }
{
/// <summary>
} /// Called in base class constructor before RVI and GUID files are built
/// </summary>
/// <summary> protected override void ExecuteCustomSteps()
/// Called in base class constructor before RVI and GUID files are built {
/// </summary> SetUpCodec();
protected override void ExecuteCustomSteps() }
{
SetUpCodec(); /// <summary>
} /// Creates a static asset for the codec and maps the joins to the main room symbol
/// </summary>
/// <summary> private void SetUpCodec()
/// Creates a static asset for the codec and maps the joins to the main room symbol {
/// </summary> try
void SetUpCodec() {
{ var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
try if (essentialsHuddleVtc1Room == null)
{ {
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; return;
}
if (codec == null)
{ var codec = essentialsHuddleVtc1Room.VideoCodec;
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
return; if (codec == null)
} {
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
codec.UsageTracker = new UsageTracking(codec); return;
codec.UsageTracker.UsageIsTracked = true; }
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
codec.UsageTracker = new UsageTracking(codec) {UsageIsTracked = true};
var codecPowerOnAction = new Action<bool>(b => { if (!b) codec.StandbyDeactivate(); }); codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var codecPowerOffAction = new Action<bool>(b => { if (!b) codec.StandbyActivate(); });
var codecPowerOnAction = new Action<bool>(b =>
// Map FusionRoom Attributes: {
if (!b)
// Codec volume {
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); codec.StandbyDeactivate();
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b)); }
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig); });
var codecPowerOffAction = new Action<bool>(b =>
// In Call Status {
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); if (!b)
codec.CallStatusChange += new EventHandler<Core.Devices.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange); {
codec.StandbyActivate();
// Online status }
if (codec is ICommunicationMonitor) });
{
var c = codec as ICommunicationMonitor; // Map FusionRoom Attributes:
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk; // Codec volume
c.CommunicationMonitor.StatusChange += (o, a) => var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
{ codecVolume.OutputSig.UserObject =
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
}; (codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
} // In Call Status
_codecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
// Codec IP Address codec.CallStatusChange += codec_CallStatusChange;
bool codecHasIpInfo = false;
var codecComm = codec.Communication; // Online status
if (codec is ICommunicationMonitor)
string codecIpAddress = string.Empty; {
int codecIpPort = 0; var c = codec as ICommunicationMonitor;
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
StringSigData codecIpAddressSig; codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
StringSigData codecIpPortSig; c.CommunicationMonitor.StatusChange +=
(o, a) => { codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
if(codecComm is GenericSshClient) Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key,
{ "Online - VC 1");
codecIpAddress = (codecComm as GenericSshClient).Hostname; }
codecIpPort = (codecComm as GenericSshClient).Port;
codecHasIpInfo = true; // Codec IP Address
} bool codecHasIpInfo = false;
else if (codecComm is GenericTcpIpClient) var codecComm = codec.Communication;
{
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname; string codecIpAddress = string.Empty;
codecIpPort = (codecComm as GenericTcpIpClient).Port; int codecIpPort = 0;
codecHasIpInfo = true;
} if (codecComm is GenericSshClient)
{
if (codecHasIpInfo) codecIpAddress = (codecComm as GenericSshClient).Hostname;
{ codecIpPort = (codecComm as GenericSshClient).Port;
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly); codecHasIpInfo = true;
codecIpAddressSig.InputSig.StringValue = codecIpAddress; }
else if (codecComm is GenericTcpIpClient)
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly); {
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
} codecIpPort = (codecComm as GenericTcpIpClient).Port;
codecHasIpInfo = true;
var tempAsset = new FusionAsset(); }
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key)); if (codecHasIpInfo)
{
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) StringSigData codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC",
{ eSigIoMask.InputSigOnly);
tempAsset = FusionStaticAssets[deviceConfig.Uid]; codecIpAddressSig.InputSig.StringValue = codecIpAddress;
}
else StringSigData codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC",
{ eSigIoMask.InputSigOnly);
// Create a new asset codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name, "Codec", ""); }
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
} FusionAsset tempAsset;
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction; if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig); {
tempAsset = FusionStaticAssets[deviceConfig.Uid];
// TODO: Map relevant attributes on asset symbol }
else
codecAsset.TrySetMakeModel(codec); {
codecAsset.TryLinkAssetErrorToCommunication(codec); // Create a new asset
} tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name,
catch (Exception e) "Codec", "");
{ FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e); }
}
} var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
void codec_CallStatusChange(object sender, Core.Devices.Codec.CodecCallStatusItemChangeEventArgs e) codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
{ codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
CodecIsInCall.InputSig.BoolValue = codec.IsInCall; // TODO: Map relevant attributes on asset symbol
}
codecAsset.TrySetMakeModel(codec);
// These methods are overridden because they access the room class which is of a different type codecAsset.TryLinkAssetErrorToCommunication(codec);
}
protected override void CreateSymbolAndBasicSigs(uint ipId) catch (Exception e)
{ {
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
}
FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); }
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
FusionRoom.ExtenderFusionRoomDataReservedSigs.Use(); private void codec_CallStatusChange(object sender, Core.Devices.Codec.CodecCallStatusItemChangeEventArgs e)
{
FusionRoom.Register(); var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
FusionRoom.FusionStateChange += FusionRoom_FusionStateChange; {
return;
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange; }
FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange; var codec = essentialsHuddleVtc1Room.VideoCodec;
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
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(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator); // These methods are overridden because they access the room class which is of a different type
// Room to fusion room protected override void CreateSymbolAndBasicSigs(uint ipId)
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); {
Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid);
// Moved to
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly); FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid);
// Don't think we need to get current status of this as nothing should be alive yet. FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use();
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange; FusionRoom.ExtenderFusionRoomDataReservedSigs.Use();
FusionRoom.Register();
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey)); FusionRoom.FusionStateChange += FusionRoom_FusionStateChange;
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange +=
FusionRoomSchedule_DeviceExtenderSigChange;
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange +=
} ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange;
FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange;
protected override void SetUpSources()
{ CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule",
// Sources "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey); CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod",
if (dict != null) "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
{ CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting",
// NEW PROCESS: "Creates and Ad Hoc meeting for on hour or until the next meeting",
// Make these lists and insert the fusion attributes by iterating these ConsoleAccessLevelEnum.AccessOperator);
var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
uint i = 1; // Room to fusion room
foreach (var kvp in setTopBoxes) Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
{
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); // Moved to
i++; CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source",
if (i > 5) // We only have five spots eSigIoMask.InputSigOnly);
break; // Don't think we need to get current status of this as nothing should be alive yet.
}
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); if (essentialsHuddleVtc1Room != null)
i = 1; {
foreach (var kvp in discPlayers) essentialsHuddleVtc1Room.CurrentSourceChange += Room_CurrentSourceInfoChange;
{ FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); essentialsHuddleVtc1Room.PowerOnToDefaultOrLastSource);
i++; FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(
if (i > 5) // We only have five spots () => essentialsHuddleVtc1Room.RunRouteAction("roomOff", Room.SourceListKey));
break; }
}
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop); }
i = 1;
foreach (var kvp in laptops) protected override void SetUpSources()
{ {
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); // Sources
i++; var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (i > 10) // We only have ten spots???
break; if (essentialsHuddleVtc1Room == null)
} {
return;
foreach (var kvp in dict) }
{
var usageDevice = kvp.Value.SourceDevice as IUsageTracking; var dict = ConfigReader.ConfigObject.GetSourceListForKey(essentialsHuddleVtc1Room.SourceListKey);
if (dict != null)
if (usageDevice != null) {
{ // NEW PROCESS:
usageDevice.UsageTracker = new UsageTracking(usageDevice as Device); // Make these lists and insert the fusion attributes by iterating these
usageDevice.UsageTracker.UsageIsTracked = true; var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls);
usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded); uint i = 1;
} foreach (var kvp in setTopBoxes)
} {
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
} i++;
else if (i > 5) // We only have five spots
{ {
Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", break;
(Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key); }
} }
}
var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls);
protected override void SetUpDisplay() i = 1;
{ foreach (var kvp in discPlayers)
try {
{ TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
//Setup Display Usage Monitoring i++;
if (i > 5) // We only have five spots
var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase); {
break;
// Consider updating this in multiple display systems }
}
foreach (DisplayBase display in displays)
{ var laptops = dict.Where(d => d.Value.SourceDevice is Core.Devices.Laptop);
display.UsageTracker = new UsageTracking(display); i = 1;
display.UsageTracker.UsageIsTracked = true; foreach (var kvp in laptops)
display.UsageTracker.DeviceUsageEnded += new EventHandler<DeviceUsageEventArgs>(UsageTracker_DeviceUsageEnded); {
} TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
i++;
var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; if (i > 10) // We only have ten spots???
if (defaultDisplay == null) {
{ break;
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); }
return; }
}
foreach (var usageDevice in dict.Select(kvp => kvp.Value.SourceDevice).OfType<IUsageTracking>())
var dispPowerOnAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOn(); }); {
var dispPowerOffAction = new Action<bool>(b => { if (!b) defaultDisplay.PowerOff(); }); usageDevice.UsageTracker = new UsageTracking(usageDevice as Device) {UsageIsTracked = true};
usageDevice.UsageTracker.DeviceUsageEnded +=
// Display to fusion room sigs UsageTracker_DeviceUsageEnded;
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; }
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; }
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); else
if (defaultDisplay is IDisplayUsage) {
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'",
essentialsHuddleVtc1Room.SourceListKey, Room.Key);
}
}
MapDisplayToRoomJoins(1, 158, defaultDisplay);
protected override void SetUpDisplay()
{
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); try
{
//Check for existing asset in GUIDs collection //Setup Display Usage Monitoring
var tempAsset = new FusionAsset(); var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase);
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid)) // Consider updating this in multiple display systems
{
tempAsset = FusionStaticAssets[deviceConfig.Uid]; foreach (var display in displays.Cast<DisplayBase>())
} {
else display.UsageTracker = new UsageTracking(display) {UsageIsTracked = true};
{ display.UsageTracker.DeviceUsageEnded +=
// Create a new asset UsageTracker_DeviceUsageEnded;
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), defaultDisplay.Name, "Display", ""); }
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
} var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId); {
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction; return;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction; }
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig); var defaultDisplay = essentialsHuddleVtc1Room.DefaultDisplay as DisplayBase;
// Use extension methods if (defaultDisplay == null)
dispAsset.TrySetMakeModel(defaultDisplay); {
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay); Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
} return;
catch (Exception e) }
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e); var dispPowerOnAction = new Action<bool>(b =>
} {
if (!b)
} {
defaultDisplay.PowerOn();
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) }
{ });
string displayName = string.Format("Display {0} - ", displayIndex); var dispPowerOffAction = new Action<bool>(b =>
{
if (!b)
if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay) {
{ defaultDisplay.PowerOff();
// Power on }
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); });
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); // Display to fusion room sigs
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
// Power Off FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig); defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ; if (defaultDisplay is IDisplayUsage)
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); {
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
// Current Source }
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); }); ;
} MapDisplayToRoomJoins(1, 158, defaultDisplay);
}
}
var deviceConfig =
ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
FusionAsset tempAsset;
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
defaultDisplay.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up display in Fusion: {0}", e);
}
}
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
{
var displayName = string.Format("Display {0} - ", displayIndex);
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null || display != essentialsHuddleVtc1Room.DefaultDisplay)
{
return;
}
// Power on
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint) joinOffset, displayName + "Power On",
eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
{
if (!b)
{
display.PowerOn();
}
});
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Power Off
FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 1,
displayName + "Power Off", eSigIoMask.InputOutputSig);
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b =>
{
if (!b)
{
display.PowerOff();
}
});
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
// Current Source
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint) joinOffset + 8,
displayName + "Source None", eSigIoMask.InputOutputSig);
defaultDisplaySourceNone.OutputSig.UserObject = new Action<bool>(b =>
{
if (b)
{
return;
}
var huddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (huddleVtc1Room != null)
{
huddleVtc1Room.RunRouteAction("roomOff", Room.SourceListKey);
}
});
}
}
} }

View File

@@ -0,0 +1,225 @@
using System;
using System.Linq;
using Crestron.SimplSharpPro;
using PepperDash.Core;
using PepperDash.Essentials.Core.Config;
namespace PepperDash.Essentials.Core.Fusion
{
public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase
{
private BooleanSigData _codecIsInCall;
private readonly EssentialsHuddleVtc1Room _room;
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
: base(room, ipId)
{
_room = room;
}
/// <summary>
/// Called in base class constructor before RVI and GUID files are built
/// </summary>
protected override void ExecuteCustomSteps()
{
SetUpCodec();
base.ExecuteCustomSteps();
}
/// <summary>
/// Creates a static asset for the codec and maps the joins to the main room symbol
/// </summary>
private void SetUpCodec()
{
try
{
var essentialsHuddleVtc1Room = Room as EssentialsHuddleVtc1Room;
if (essentialsHuddleVtc1Room == null)
{
return;
}
var codec = essentialsHuddleVtc1Room.VideoCodec;
if (codec == null)
{
Debug.Console(1, this, "Cannot link codec to Fusion because codec is null");
return;
}
codec.UsageTracker = new UsageTracking(codec) {UsageIsTracked = true};
codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
var codecPowerOnAction = new Action<bool>(b =>
{
if (!b)
{
codec.StandbyDeactivate();
}
});
var codecPowerOffAction = new Action<bool>(b =>
{
if (!b)
{
codec.StandbyActivate();
}
});
// Map FusionRoom Attributes:
// Codec volume
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
codecVolume.OutputSig.UserObject =
new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
// In Call Status
_codecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
codec.CallStatusChange += codec_CallStatusChange;
// Online status
if (codec is ICommunicationMonitor)
{
var c = codec as ICommunicationMonitor;
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
c.CommunicationMonitor.StatusChange +=
(o, a) => { codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk; };
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key,
"Online - VC 1");
}
// Codec IP Address
var codecHasIpInfo = false;
var codecComm = codec.Communication;
var codecIpAddress = string.Empty;
var codecIpPort = 0;
if (codecComm is GenericSshClient)
{
codecIpAddress = (codecComm as GenericSshClient).Hostname;
codecIpPort = (codecComm as GenericSshClient).Port;
codecHasIpInfo = true;
}
else if (codecComm is GenericTcpIpClient)
{
codecIpAddress = (codecComm as GenericTcpIpClient).Hostname;
codecIpPort = (codecComm as GenericTcpIpClient).Port;
codecHasIpInfo = true;
}
if (codecHasIpInfo)
{
var codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC",
eSigIoMask.InputSigOnly);
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
var codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC",
eSigIoMask.InputSigOnly);
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
}
FusionAsset tempAsset;
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(c => c.Key.Equals(codec.Key));
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom), codec.Name,
"Codec", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
// TODO: Map relevant attributes on asset symbol
codecAsset.TrySetMakeModel(codec);
codecAsset.TryLinkAssetErrorToCommunication(codec);
}
catch (Exception e)
{
Debug.Console(1, this, "Error setting up codec in Fusion: {0}", e);
}
}
#region Overrides of EssentialsHuddleSpaceFusionSystemControllerBase
protected override void SetUpDisplay()
{
base.SetUpDisplay();
var defaultDisplay = _room.DefaultDisplay as DisplayBase;
if (defaultDisplay == null)
{
Debug.Console(1, this, "Cannot link null display to Fusion because default display is null");
return;
}
var deviceConfig =
ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
//Check for existing asset in GUIDs collection
FusionAsset tempAsset;
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
{
tempAsset = FusionStaticAssets[deviceConfig.Uid];
}
else
{
// Create a new asset
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
defaultDisplay.Name, "Display", "");
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
}
var dispPowerOnAction = new Action<bool>(b =>
{
if (!b)
{
defaultDisplay.PowerOn();
}
});
var dispPowerOffAction = new Action<bool>(b =>
{
if (!b)
{
defaultDisplay.PowerOff();
}
});
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
tempAsset.InstanceId);
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
// Use extension methods
dispAsset.TrySetMakeModel(defaultDisplay);
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
}
#endregion
private void codec_CallStatusChange(object sender, Devices.Codec.CodecCallStatusItemChangeEventArgs e)
{
var codec = _room.VideoCodec;
_codecIsInCall.InputSig.BoolValue = codec.IsInCall;
}
}
}

View File

@@ -41,43 +41,43 @@ namespace PepperDash.Essentials.Core.Fusion
var devProps = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(deviceConfig.Properties.ToString()); var devProps = JsonConvert.DeserializeObject<RoomOnToDefaultSourceWhenOccupiedConfig>(deviceConfig.Properties.ToString());
var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupied")); var enableFeature = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupied"));
if (enableFeature != null) if (enableFeature != null)
devProps.EnableRoomOnWhenOccupied = bool.Parse(enableFeature.CustomFieldValue); devProps.EnableRoomOnWhenOccupied = bool.Parse(enableFeature.CustomFieldValue);
var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedStartTime")); var enableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("RoomOnWhenOccupiedStartTime"));
if (enableTime != null) if (enableTime != null)
devProps.OccupancyStartTime = enableTime.CustomFieldValue; devProps.OccupancyStartTime = enableTime.CustomFieldValue;
var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomOnWhenOccupiedEndTime")); var disableTime = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("RoomOnWhenOccupiedEndTime"));
if (disableTime != null) if (disableTime != null)
devProps.OccupancyEndTime = disableTime.CustomFieldValue; devProps.OccupancyEndTime = disableTime.CustomFieldValue;
var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSun")); var enableSunday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedSun"));
if (enableSunday != null) if (enableSunday != null)
devProps.EnableSunday = bool.Parse(enableSunday.CustomFieldValue); devProps.EnableSunday = bool.Parse(enableSunday.CustomFieldValue);
var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedMon")); var enableMonday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedMon"));
if (enableMonday != null) if (enableMonday != null)
devProps.EnableMonday = bool.Parse(enableMonday.CustomFieldValue); devProps.EnableMonday = bool.Parse(enableMonday.CustomFieldValue);
var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedTue")); var enableTuesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedTue"));
if (enableTuesday != null) if (enableTuesday != null)
devProps.EnableTuesday = bool.Parse(enableTuesday.CustomFieldValue); devProps.EnableTuesday = bool.Parse(enableTuesday.CustomFieldValue);
var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedWed")); var enableWednesday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedWed"));
if (enableWednesday != null) if (enableWednesday != null)
devProps.EnableWednesday = bool.Parse(enableWednesday.CustomFieldValue); devProps.EnableWednesday = bool.Parse(enableWednesday.CustomFieldValue);
var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedThu")); var enableThursday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedThu"));
if (enableThursday != null) if (enableThursday != null)
devProps.EnableThursday = bool.Parse(enableThursday.CustomFieldValue); devProps.EnableThursday = bool.Parse(enableThursday.CustomFieldValue);
var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedFri")); var enableFriday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedFri"));
if (enableFriday != null) if (enableFriday != null)
devProps.EnableFriday = bool.Parse(enableFriday.CustomFieldValue); devProps.EnableFriday = bool.Parse(enableFriday.CustomFieldValue);
var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("EnRoomOnWhenOccupiedSat")); var enableSaturday = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("EnRoomOnWhenOccupiedSat"));
if (enableSaturday != null) if (enableSaturday != null)
devProps.EnableSaturday = bool.Parse(enableSaturday.CustomFieldValue); devProps.EnableSaturday = bool.Parse(enableSaturday.CustomFieldValue);
@@ -96,7 +96,7 @@ namespace PepperDash.Essentials.Core.Fusion
} }
// Set the help message // Set the help message
var helpMessage = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.ID.Equals("RoomHelpMessage")); var helpMessage = roomInfo.FusionCustomProperties.FirstOrDefault(p => p.Id.Equals("RoomHelpMessage"));
if (helpMessage != null) if (helpMessage != null)
{ {
//Debug.Console(1, "Current Help Message: {0}. New Help Message: {1}", deviceConfig.Properties["help"]["message"].Value<string>(ToString()), helpMessage.CustomFieldValue); //Debug.Console(1, "Current Help Message: {0}. New Help Message: {1}", deviceConfig.Properties["help"]["message"].Value<string>(ToString()), helpMessage.CustomFieldValue);