diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index 1aeb50aa..187939c5 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -27,14 +27,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco { public event EventHandler DirectoryResultReturned; - public IBasicCommunication Communication { get; private set; } public CommunicationGather PortGather { get; private set; } public CommunicationGather JsonGather { get; private set; } public StatusMonitorBase CommunicationMonitor { get; private set; } - public BoolFeedback StandbyIsOnFeedback { get; private set; } - public BoolFeedback RoomIsOccupiedFeedback { get; private set; } public IntFeedback PeopleCountFeedback { get; private set; } @@ -114,7 +111,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco } } - protected Func StandbyStateFeedbackFunc + protected override Func StandbyIsOnFeedbackFunc { get { @@ -230,7 +227,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public CiscoSparkCodec(string key, string name, IBasicCommunication comm, CiscoSparkCodecPropertiesConfig props ) : base(key, name) { - StandbyIsOnFeedback = new BoolFeedback(StandbyStateFeedbackFunc); RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc); PeopleCountFeedback = new IntFeedback(PeopleCountFeedbackFunc); SpeakerTrackIsOnFeedback = new BoolFeedback(SpeakerTrackIsOnFeedbackFunc); @@ -1080,7 +1076,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// /// Puts the codec in standby mode /// - public void StandbyActivate() + public override void StandbyActivate() { SendText("xCommand Standby Activate"); } @@ -1088,7 +1084,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco /// /// Wakes the codec from standby /// - public void StandbyDeactivate() + public override void StandbyDeactivate() { SendText("xCommand Standby Deactivate"); } diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs index c8b3c9d8..63288835 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/MockVC/MockVC.cs @@ -87,6 +87,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec } int _VolumeLevel; + protected override Func StandbyIsOnFeedbackFunc + { + get { return () => _StandbyIsOn; } + } + bool _StandbyIsOn; + + /// /// Dials, yo! /// @@ -182,6 +189,16 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec { } + public override void StandbyActivate() + { + _StandbyIsOn = true; + } + + public override void StandbyDeactivate() + { + _StandbyIsOn = false; + } + /// /// Called by routing to make it happen /// diff --git a/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs b/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs index 6fb3d5b4..37853236 100644 --- a/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs +++ b/Essentials Devices Common/Essentials Devices Common/VideoCodec/VideoCodecBase.cs @@ -21,6 +21,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public event EventHandler IsReadyChange; + public IBasicCommunication Communication { get; protected set; } + #region IUsageTracking Members /// @@ -40,10 +42,13 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public bool IsInCall { get { return ActiveCalls.Any(c => c.IsActiveCall); } } + public BoolFeedback StandbyIsOnFeedback { get; private set; } + abstract protected Func PrivacyModeIsOnFeedbackFunc { get; } abstract protected Func VolumeLevelFeedbackFunc { get; } abstract protected Func MuteFeedbackFunc { get; } abstract protected Func SharingSourceFeedbackFunc { get; } + abstract protected Func StandbyIsOnFeedbackFunc { get; } public List ActiveCalls { get; set; } @@ -58,6 +63,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec public VideoCodecBase(string key, string name) : base(key, name) { + StandbyIsOnFeedback = new BoolFeedback(StandbyIsOnFeedbackFunc); PrivacyModeIsOnFeedback = new BoolFeedback(PrivacyModeIsOnFeedbackFunc); VolumeLevelFeedback = new IntFeedback(VolumeLevelFeedbackFunc); MuteFeedback = new BoolFeedback(MuteFeedbackFunc); @@ -180,6 +186,10 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec Debug.Console(1, this, "\n{0}\n", sb.ToString()); } + public abstract void StandbyActivate(); + + public abstract void StandbyDeactivate(); + } diff --git a/Essentials/PepperDashEssentials/ControlSystem.cs b/Essentials/PepperDashEssentials/ControlSystem.cs index 8ef6b09f..6c74b9bc 100644 --- a/Essentials/PepperDashEssentials/ControlSystem.cs +++ b/Essentials/PepperDashEssentials/ControlSystem.cs @@ -204,6 +204,7 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(room); Debug.Console(1, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1)); } else { diff --git a/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs b/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs index 23d059f0..40da2213 100644 --- a/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs +++ b/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleSpaceFusionSystemControllerBase.cs @@ -30,14 +30,14 @@ namespace PepperDash.Essentials.Fusion //public event EventHandler MeetingEndWarning; //public event EventHandler NextMeetingBeginWarning; - FusionRoom FusionRoom; - EssentialsHuddleSpaceRoom Room; + protected FusionRoom FusionRoom; + protected EssentialsRoomBase Room; Dictionary SourceToFeedbackSigs = new Dictionary(); StatusMonitorCollection ErrorMessageRollUp; - StringSigData CurrentRoomSourceNameSig; + protected StringSigData CurrentRoomSourceNameSig; #region System Info Sigs //StringSigData SystemName; @@ -76,7 +76,7 @@ namespace PepperDash.Essentials.Fusion Event CurrentMeeting; - string RoomGuid + protected string RoomGuid { get { @@ -102,13 +102,13 @@ namespace PepperDash.Essentials.Fusion public long PushNotificationTimeout = 5000; - Dictionary FusionStaticAssets; + protected Dictionary FusionStaticAssets; // For use with local occ sensor devices which will relay to Fusion the current occupancy status - FusionRemoteOccupancySensor FusionRemoteOccSensor; + protected FusionRemoteOccupancySensor FusionRemoteOccSensor; // For use with occ sensor attached to a scheduling panel in Fusion - FusionOccupancySensorAsset FusionOccSensor; + protected FusionOccupancySensorAsset FusionOccSensor; public BoolFeedback RoomIsOccupiedFeedback { get; private set; } @@ -122,7 +122,7 @@ namespace PepperDash.Essentials.Fusion //ScheduleResponseEvent NextMeeting; - public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsHuddleSpaceRoom room, uint ipId) + public EssentialsHuddleSpaceFusionSystemControllerBase(EssentialsRoomBase room, uint ipId) : base(room.Key + "-fusion") { @@ -156,6 +156,7 @@ namespace PepperDash.Essentials.Fusion SetUpCommunitcationMonitors(); SetUpDisplay(); SetUpError(); + ExecuteCustomSteps(); if(Room.RoomOccupancy != null) { @@ -173,6 +174,14 @@ namespace PepperDash.Essentials.Fusion GenerateGuidFile(guidFilePath); } + /// + /// Used for extension classes to execute whatever steps are necessary before generating the RVI and GUID files + /// + protected virtual void ExecuteCustomSteps() + { + + } + /// /// Generates the guid file in NVRAM. If the file already exists it will be overwritten. /// @@ -277,7 +286,7 @@ namespace PepperDash.Essentials.Fusion } - void CreateSymbolAndBasicSigs(uint ipId) + protected virtual void CreateSymbolAndBasicSigs(uint ipId) { Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); @@ -303,11 +312,11 @@ namespace PepperDash.Essentials.Fusion // Moved to 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. - Room.CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange); + (Room as EssentialsHuddleSpaceRoom).CurrentSingleSourceChange += new SourceInfoChangeHandler(Room_CurrentSourceInfoChange); - FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction(Room.PowerOnToDefaultOrLastSource); - FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => Room.RunRouteAction("roomOff")); + FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleSpaceRoom).PowerOnToDefaultOrLastSource); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff")); // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); FusionRoom.ErrorMessage.InputSig.StringValue = "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; @@ -321,7 +330,7 @@ namespace PepperDash.Essentials.Fusion CrestronEnvironment.EthernetEventHandler += new EthernetEventHandler(CrestronEnvironment_EthernetEventHandler); } - void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs) + protected void CrestronEnvironment_EthernetEventHandler(EthernetEventArgs ethernetEventArgs) { if (ethernetEventArgs.EthernetEventType == eEthernetEventType.LinkUp) { @@ -329,7 +338,7 @@ namespace PepperDash.Essentials.Fusion } } - void GetSystemInfo() + protected void GetSystemInfo() { //SystemName.InputSig.StringValue = Room.Name; //Model.InputSig.StringValue = InitialParametersClass.ControllerPromptName; @@ -341,7 +350,7 @@ namespace PepperDash.Essentials.Fusion systemReboot.OutputSig.SetSigFalseAction(() => CrestronConsole.SendControlSystemCommand("reboot", ref response)); } - void GetProcessorEthernetValues() + protected void GetProcessorEthernetValues() { Ip1 = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - IP 1", eSigIoMask.InputSigOnly); Ip2 = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - IP 2", eSigIoMask.InputSigOnly); @@ -379,7 +388,7 @@ namespace PepperDash.Essentials.Fusion } } - void GetProcessorInfo() + protected void GetProcessorInfo() { //SystemName = FusionRoom.CreateOffsetStringSig(50, "Info - Processor - System Name", eSigIoMask.InputSigOnly); //Model = FusionRoom.CreateOffsetStringSig(51, "Info - Processor - Model", eSigIoMask.InputSigOnly); @@ -414,7 +423,7 @@ namespace PepperDash.Essentials.Fusion // TODO Get IP and Project Name from TP } - void FusionRoom_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) + protected void FusionRoom_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args) { if (args.DeviceOnLine) { @@ -609,7 +618,7 @@ namespace PepperDash.Essentials.Fusion /// /// /// - void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) + protected void ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) { Debug.Console(2, this, "Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); @@ -725,7 +734,7 @@ namespace PepperDash.Essentials.Fusion /// /// /// - void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) + protected void FusionRoomSchedule_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args) { Debug.Console(2, this, "Scehdule Response Event: {0}\n Sig: {1}\nFusionResponse:\n{2}", args.Event, args.Sig.Name, args.Sig.StringValue); @@ -861,10 +870,10 @@ namespace PepperDash.Essentials.Fusion } } - void SetUpSources() + protected virtual void SetUpSources() { // Sources - var dict = ConfigReader.ConfigObject.GetSourceListForKey(Room.SourceListKey); + var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleSpaceRoom).SourceListKey); if (dict != null) { // NEW PROCESS: @@ -915,7 +924,7 @@ namespace PepperDash.Essentials.Fusion else { Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", - Room.SourceListKey, Room.Key); + (Room as EssentialsHuddleSpaceRoom).SourceListKey, Room.Key); } } @@ -924,7 +933,7 @@ namespace PepperDash.Essentials.Fusion /// /// /// - void UsageTracker_DeviceUsageEnded(object sender, DeviceUsageEventArgs e) + protected void UsageTracker_DeviceUsageEnded(object sender, DeviceUsageEventArgs e) { var deviceTracker = sender as UsageTracking; @@ -950,7 +959,7 @@ namespace PepperDash.Essentials.Fusion } - void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) + protected void TryAddRouteActionSigs(string attrName, uint attrNum, string routeKey, Device pSrc) { Debug.Console(2, this, "Creating attribute '{0}' with join {1} for source {2}", attrName, attrNum, pSrc.Key); @@ -962,7 +971,7 @@ namespace PepperDash.Essentials.Fusion SourceToFeedbackSigs.Add(pSrc, sigD.InputSig); // And respond to selection in Fusion - sigD.OutputSig.SetSigFalseAction(() => Room.RunRouteAction(routeKey)); + sigD.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleSpaceRoom).RunRouteAction(routeKey)); } catch (Exception) { @@ -1044,7 +1053,7 @@ namespace PepperDash.Essentials.Fusion } } - void SetUpDisplay() + protected virtual void SetUpDisplay() { try { @@ -1061,10 +1070,10 @@ namespace PepperDash.Essentials.Fusion display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); } - var defaultDisplay = Room.DefaultDisplay as DisplayBase; + var defaultDisplay = (Room as EssentialsHuddleSpaceRoom).DefaultDisplay as DisplayBase; if (defaultDisplay == null) { - Debug.Console(1, this, "Cannot link null display to Fusion"); + Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); return; } @@ -1121,12 +1130,12 @@ namespace PepperDash.Essentials.Fusion /// /// /// a - void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) + protected virtual void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) { string displayName = string.Format("Display {0} - ", displayIndex); - if(display == Room.DefaultDisplay) + if (display == (Room as EssentialsHuddleSpaceRoom).DefaultDisplay) { // Display volume var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); @@ -1145,37 +1154,10 @@ namespace PepperDash.Essentials.Fusion // Current Source var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig); - defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) Room.RunRouteAction("roomOff"); }); ; - - //var dict = ConfigReader.ConfigObject.GetSourceListForKey(Room.SourceListKey); - - //foreach (var item in dict) - //{ - // if(item.Key != "roomOff") - // { - // var defaultDisplaySource = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + (uint)item.Value.Order + 9 , string.Format("{0}Source {1}", displayIndex, item.Value.Order), eSigIoMask.InputOutputSig); - // defaultDisplaySource.OutputSig.UserObject = new Action(b => { if (!b) Room.RunRouteAction(item.Key); }); - - // //defaultDisplaySource.InputSig = Source[item.Value.Order].InputSig; - // } - - //} + defaultDisplaySourceNone.OutputSig.UserObject = new Action(b => { if (!b) (Room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff"); }); ; } } - //void Room_CurrentSingleSourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) - //{ - // for (int i = 1; i <= Source.Length; i++) - // { - // Source[i].InputSig.BoolValue = false; - // } - - // Source[info.Order].InputSig.BoolValue = true; - - // // Need to check for current source key against source list and update Source[] BooleanSigData as appropriate - - //} - void SetUpError() { // Roll up ALL device errors @@ -1262,7 +1244,7 @@ namespace PepperDash.Essentials.Fusion /// /// Event handler for when room source changes /// - void Room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) + protected void Room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type) { // Handle null. Nothing to do when switching from or to null if (info == null || info.SourceDevice == null) @@ -1283,7 +1265,7 @@ namespace PepperDash.Essentials.Fusion } } - void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args) + protected void FusionRoom_FusionStateChange(FusionBase device, FusionStateEventArgs args) { // The sig/UO method: Need separate handlers for fixed and user sigs, all flavors, diff --git a/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleVtc1FusionController.cs b/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleVtc1FusionController.cs index 273ae752..f1c90c84 100644 --- a/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/Essentials/PepperDashEssentials/OTHER/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -2,7 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; + using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.DeviceSupport; +using Crestron.SimplSharpPro.Fusion; + using PepperDash.Core; using PepperDash.Essentials; @@ -14,11 +20,336 @@ namespace PepperDash.Essentials.Fusion { public class EssentialsHuddleVtc1FusionController : EssentialsHuddleSpaceFusionSystemControllerBase { - public EssentialsHuddleVtc1FusionController(EssentialsHuddleSpaceRoom room, uint ipId) + BooleanSigData CodecIsInCall; + + public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId) : base(room, ipId) { + } + /// + /// Called in base class constructor before RVI and GUID files are built + /// + protected override void ExecuteCustomSteps() + { + SetUpCodec(); + } + + /// + /// Creates a static asset for the codec and maps the joins to the main room symbol + /// + void SetUpCodec() + { + try + { + var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; + + if (codec == null) + { + Debug.Console(1, this, "Cannot link codec to Fusion because codec is null"); + return; + } + + codec.UsageTracker = new UsageTracking(codec); + codec.UsageTracker.UsageIsTracked = true; + codec.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded; + + var codecPowerOnAction = new Action(b => { if (!b) codec.StandbyDeactivate(); }); + var codecPowerOffAction = new Action(b => { if (!b) codec.StandbyActivate(); }); + + + // Map FusionRoom Attributes: + + // In Call Status + CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly); + codec.CallStatusChange += new EventHandler(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 + bool codecHasIpInfo = false; + var codecComm = codec.Communication; + + string codecIpAddress = string.Empty; + int codecIpPort = 0; + + StringSigData codecIpAddressSig; + StringSigData codecIpPortSig; + + 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) + { + codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly); + codecIpAddressSig.InputSig.StringValue = codecIpAddress; + + codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly); + codecIpPortSig.InputSig.StringValue = codecIpPort.ToString(); + } + + var tempAsset = new FusionAsset(); + + 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); + } + } + + void codec_CallStatusChange(object sender, PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs e) + { + var codec = (Room as EssentialsHuddleVtc1Room).VideoCodec; + + CodecIsInCall.InputSig.BoolValue = codec.IsInCall; + } + + // These methods are overridden because they access the room class which is of a different type + + protected override void CreateSymbolAndBasicSigs(uint ipId) + { + Debug.Console(1, this, "Creating Fusion Room symbol with GUID: {0}", RoomGuid); + + FusionRoom = new FusionRoom(ipId, Global.ControlSystem, Room.Name, RoomGuid); + FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.Use(); + FusionRoom.ExtenderFusionRoomDataReservedSigs.Use(); + + FusionRoom.Register(); + + FusionRoom.FusionStateChange += FusionRoom_FusionStateChange; + + FusionRoom.ExtenderRoomViewSchedulingDataReservedSigs.DeviceExtenderSigChange += FusionRoomSchedule_DeviceExtenderSigChange; + FusionRoom.ExtenderFusionRoomDataReservedSigs.DeviceExtenderSigChange += ExtenderFusionRoomDataReservedSigs_DeviceExtenderSigChange; + FusionRoom.OnlineStatusChange += FusionRoom_OnlineStatusChange; + + 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); + + // Room to fusion room + Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig); + + // Moved to + 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. + (Room as EssentialsHuddleVtc1Room).CurrentSingleSourceChange += Room_CurrentSourceInfoChange; + + + FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource); + FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff")); + // NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig); + FusionRoom.ErrorMessage.InputSig.StringValue = + "3: 7 Errors: This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;This is a really long error message;"; + + GetProcessorEthernetValues(); + + GetSystemInfo(); + + GetProcessorInfo(); + + CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler; + } + + protected override void SetUpSources() + { + // Sources + var dict = ConfigReader.ConfigObject.GetSourceListForKey((Room as EssentialsHuddleVtc1Room).SourceListKey); + if (dict != null) + { + // NEW PROCESS: + // Make these lists and insert the fusion attributes by iterating these + var setTopBoxes = dict.Where(d => d.Value.SourceDevice is ISetTopBoxControls); + uint i = 1; + foreach (var kvp in setTopBoxes) + { + TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + break; + } + + var discPlayers = dict.Where(d => d.Value.SourceDevice is IDiscPlayerControls); + i = 1; + foreach (var kvp in discPlayers) + { + TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 5) // We only have five spots + break; + } + + var laptops = dict.Where(d => d.Value.SourceDevice is Laptop); + i = 1; + foreach (var kvp in laptops) + { + TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice); + i++; + if (i > 10) // We only have ten spots??? + break; + } + + foreach (var kvp in dict) + { + var usageDevice = kvp.Value.SourceDevice as IUsageTracking; + + if (usageDevice != null) + { + usageDevice.UsageTracker = new UsageTracking(usageDevice as Device); + usageDevice.UsageTracker.UsageIsTracked = true; + usageDevice.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); + } + } + + } + else + { + Debug.Console(1, this, "WARNING: Config source list '{0}' not found for room '{1}'", + (Room as EssentialsHuddleVtc1Room).SourceListKey, Room.Key); + } + } + + protected override void SetUpDisplay() + { + try + { + //Setup Display Usage Monitoring + + var displays = DeviceManager.AllDevices.Where(d => d is DisplayBase); + + // Consider updating this in multiple display systems + + foreach (DisplayBase display in displays) + { + display.UsageTracker = new UsageTracking(display); + display.UsageTracker.UsageIsTracked = true; + display.UsageTracker.DeviceUsageEnded += new EventHandler(UsageTracker_DeviceUsageEnded); + } + + var defaultDisplay = (Room as EssentialsHuddleVtc1Room).DefaultDisplay as DisplayBase; + if (defaultDisplay == null) + { + Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); + return; + } + + var dispPowerOnAction = new Action(b => { if (!b) defaultDisplay.PowerOn(); }); + var dispPowerOffAction = new Action(b => { if (!b) defaultDisplay.PowerOff(); }); + + // Display to fusion room sigs + FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction; + FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction; + defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig); + if (defaultDisplay is IDisplayUsage) + (defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig); + + + + MapDisplayToRoomJoins(1, 158, defaultDisplay); + + + var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key)); + + //Check for existing asset in GUIDs collection + + var tempAsset = new FusionAsset(); + + 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) + { + string displayName = string.Format("Display {0} - ", displayIndex); + + + if (display == (Room as EssentialsHuddleVtc1Room).DefaultDisplay) + { + // Display volume + var defaultDisplayVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig); + defaultDisplayVolume.OutputSig.UserObject = new Action(b => (display as IBasicVolumeWithFeedback).SetVolume(b)); + (display as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(defaultDisplayVolume.InputSig); + + // Power on + var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig); + defaultDisplayPowerOn.OutputSig.UserObject = new Action(b => { if (!b) display.PowerOn(); }); + display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig); + + // Power Off + var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig); + defaultDisplayPowerOn.OutputSig.UserObject = new Action(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(b => { if (!b) (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff"); }); ; + } } } } \ No newline at end of file