diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 3dc62c43..3ffacd2f 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -12,10 +12,10 @@ using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Bridges; using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Fusion; using PepperDash.Essentials.Core.Rooms.Config; +using PepperDash.Essentials.Devices.Common; using PepperDash.Essentials.DM; -using PepperDash.Essentials.Fusion; -using PepperDash.Essentials.Room.Config; using Newtonsoft.Json; using PepperDash.Essentials.Core.DeviceTypeInterfaces; @@ -429,18 +429,15 @@ namespace PepperDash.Essentials foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) { var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase; - if (room == null) + if (room != null) { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);' - return; - } + if (room is EssentialsHuddleSpaceRoom) + { + DeviceManager.AddDevice(room); - var huddleRoom = room as EssentialsHuddleSpaceRoom; - var vtcRoom = room as EssentialsHuddleVtc1Room; + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1)); - if (huddleRoom != null) - { - DeviceManager.AddDevice(huddleRoom); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); @@ -450,11 +447,8 @@ namespace PepperDash.Essentials { DeviceManager.AddDevice(room); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - // Mobile Control bridge - var bridge = new MobileControlEssentialsHuddleSpaceRoomBridge(huddleRoom); - AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present - DeviceManager.AddDevice(bridge); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1)); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); @@ -466,15 +460,6 @@ namespace PepperDash.Essentials DeviceManager.AddDevice(room); } - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController(vtcRoom, 0xf1)); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); - // Mobile Control bridge - var bridge = new MobileControlEssentialsHuddleSpaceRoomBridge(room); - AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present - DeviceManager.AddDevice(bridge); - continue; } else Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key); diff --git a/PepperDashEssentials/ControlSystemOld.cs b/PepperDashEssentials/ControlSystemOld.cs new file mode 100644 index 00000000..9edbbbc3 --- /dev/null +++ b/PepperDashEssentials/ControlSystemOld.cs @@ -0,0 +1,574 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.CrestronThread; +using Crestron.SimplSharpPro.Diagnostics; +using Crestron.SimplSharp.Reflection; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Bridges; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Rooms.Config; +using PepperDash.Essentials.DM; +using PepperDash.Essentials.Fusion; +using PepperDash.Essentials.Room.Config; + +using Newtonsoft.Json; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; +using EssentialsRoomConfigHelper = PepperDash.Essentials.Core.Rooms.Config.EssentialsRoomConfigHelper; + +namespace PepperDash.Essentials +{ + public class ControlSystem : CrestronControlSystem + { + HttpLogoServer LogoServer; + + private CTimer _startTimer; + private const long StartupTime = 500; + + public ControlSystem() + : base() + { + Thread.MaxNumberOfUserThreads = 400; + Global.ControlSystem = this; + DeviceManager.Initialize(this); + SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true; + } + + /// + /// Entry point for the program + /// + public override void InitializeSystem() + { + _startTimer = new CTimer(StartSystem,StartupTime); + } + + private void StartSystem(object obj) + { + DeterminePlatform(); + + if (Debug.DoNotLoadOnNextBoot) + { + CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file", + ConsoleAccessLevelEnum.AccessOperator); + } + + CrestronConsole.AddNewConsoleCommand(PluginLoader.ReportAssemblyVersions, "reportversions", "Reports the versions of the loaded assemblies", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(PepperDash.Essentials.Core.DeviceFactory.GetDeviceFactoryTypes, "gettypes", "Gets the device types that can be built. Accepts a filter string.", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(BridgeHelper.PrintJoinMap, "getjoinmap", "map(s) for bridge or device on bridge [brKey [devKey]]", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "CONSOLE MESSAGE: {0}", s); + }, "appdebugmessage", "Writes message to log", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + foreach (var tl in TieLineCollection.Default) + CrestronConsole.ConsoleCommandResponse(" {0}\r", tl); + }, + "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + CrestronConsole.ConsoleCommandResponse + ("Current running configuration. This is the merged system and template configuration"); + CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject + (ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented)); + }, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" + + "System URL: {0}\r" + + "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); + }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); + + + CrestronConsole.AddNewConsoleCommand(DeviceManager.GetRoutingPorts, + "getroutingports", "Reports all routing ports, if any. Requires a device key", ConsoleAccessLevelEnum.AccessOperator); + + if (!Debug.DoNotLoadOnNextBoot) + { + GoWithLoad(); + return; + } + + SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true; + } + + /// + /// Determines if the program is running on a processor (appliance) or server (VC-4). + /// + /// Sets Global.FilePathPrefix and Global.ApplicationDirectoryPathPrefix based on platform + /// + public void DeterminePlatform() + { + try + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform...."); + + string filePathPrefix; + + var dirSeparator = Global.DirectorySeparator; + + string directoryPrefix; + + directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory(); + + var fullVersion = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false); + + AssemblyInformationalVersionAttribute fullVersionAtt = fullVersion[0] as AssemblyInformationalVersionAttribute; + + Global.SetAssemblyVersion(fullVersionAtt.InformationalVersion); + + if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion); + + // Check if User/ProgramX exists + if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User" + + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) + { + Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber); + filePathPrefix = directoryPrefix + dirSeparator + "User" + + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + } + // Check if Nvram/Programx exists + else if (Directory.Exists(directoryPrefix + dirSeparator + "Nvram" + + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) + { + Debug.Console(0, @"Nvram/program{0} directory found", InitialParametersClass.ApplicationNumber); + filePathPrefix = directoryPrefix + dirSeparator + "Nvram" + + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + } + // If neither exists, set path to User/ProgramX + else + { + Debug.Console(0, @"No previous directory found. Using User/program{0}", InitialParametersClass.ApplicationNumber); + filePathPrefix = directoryPrefix + dirSeparator + "User" + + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + } + } + else // Handles Linux OS (Virtual Control) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on Virtual Control Server", Global.AssemblyVersion); + + // Set path to User/ + filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator; + } + + Global.SetFilePathPrefix(filePathPrefix); + } + catch (Exception e) + { + Debug.Console(0, "Unable to Determine Platform due to Exception: {0}", e.Message); + } + } + + /// + /// Begins the process of loading resources including plugins and configuration data + /// + public void GoWithLoad() + { + try + { + Debug.SetDoNotLoadOnNextBoot(false); + + PluginLoader.AddProgramAssemblies(); + + new Core.DeviceFactory(); + new Devices.Common.DeviceFactory(); + new DM.DeviceFactory(); + new DeviceFactory(); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration"); + + var filesReady = SetupFilesystem(); + if (filesReady) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins"); + PluginLoader.LoadPlugins(); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config..."); + if (!ConfigReader.LoadConfig2()) + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Essentials Load complete with errors"); + return; + } + + Load(); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r\n" + + "-------------------------------------------------------------"); + } + else + { + Debug.Console(0, + @"---------------------------------------------- + ------------------------------------------------ + ------------------------------------------------ + Essentials file structure setup completed. + Please load config, sgd and ir files and + restart program. + ------------------------------------------------ + ------------------------------------------------ + ------------------------------------------------"); + } + + } + catch (Exception e) + { + Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r\n{0}", e); + } + finally + { + // Notify the OS that the program intitialization has completed + SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true; + } + + } + + + + /// + /// Verifies filesystem is set up. IR, SGD, and programX folders + /// + bool SetupFilesystem() + { + Debug.Console(0, "Verifying and/or creating folder structure"); + var configDir = Global.FilePathPrefix; + var configExists = Directory.Exists(configDir); + if (!configExists) + Directory.Create(configDir); + + var irDir = Global.FilePathPrefix + "ir"; + if (!Directory.Exists(irDir)) + Directory.Create(irDir); + + var sgdDir = Global.FilePathPrefix + "sgd"; + if (!Directory.Exists(sgdDir)) + Directory.Create(sgdDir); + + var pluginDir = Global.FilePathPrefix + "plugins"; + if (!Directory.Exists(pluginDir)) + Directory.Create(pluginDir); + + return configExists; + } + + /// + /// + /// + public void TearDown() + { + Debug.Console(0, "Tearing down existing system"); + DeviceManager.DeactivateAll(); + + TieLineCollection.Default.Clear(); + + foreach (var key in DeviceManager.GetDevices()) + DeviceManager.RemoveDevice(key); + + Debug.Console(0, "Tear down COMPLETE"); + } + + /// + /// + /// + void Load() + { + LoadDevices(); + LoadTieLines(); + LoadRooms(); + LoadLogoServer(); + + DeviceManager.ActivateAll(); + + var mobileControl = GetMobileControlDevice(); + + if (mobileControl == null) return; + + mobileControl.LinkSystemMonitorToAppServer(); + + } + + /// + /// Reads all devices from config and adds them to DeviceManager + /// + public void LoadDevices() + { + + // Build the processor wrapper class + DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); + + // Add global System Monitor device + if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance) + { + DeviceManager.AddDevice( + new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor")); + } + + foreach (var devConf in ConfigReader.ConfigObject.Devices) + { + + try + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}', type '{1}'", devConf.Key, devConf.Type); + // Skip this to prevent unnecessary warnings + if (devConf.Key == "processor") + { + if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower()) + Debug.Console(0, + "WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available", + devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper()); + + // Check if the processor is a DMPS model + if (this.ControllerPrompt.IndexOf("dmps", StringComparison.OrdinalIgnoreCase) > -1) + { + Debug.Console(2, "Adding DmpsRoutingController for {0} to Device Manager.", this.ControllerPrompt); + + var propertiesConfig = JsonConvert.DeserializeObject(devConf.Properties.ToString()); + + if(propertiesConfig == null) + propertiesConfig = new DM.Config.DmpsRoutingPropertiesConfig(); + + var dmpsRoutingController = DmpsRoutingController.GetDmpsRoutingController("processor-avRouting", this.ControllerPrompt, propertiesConfig); + + DeviceManager.AddDevice(dmpsRoutingController); + } + else if (this.ControllerPrompt.IndexOf("mpc3", StringComparison.OrdinalIgnoreCase) > -1) + { + Debug.Console(2, "MPC3 processor type detected. Adding Mpc3TouchpanelController."); + + var butToken = devConf.Properties["buttons"]; + if (butToken != null) + { + var buttons = butToken.ToObject>(); + var tpController = new Essentials.Core.Touchpanels.Mpc3TouchpanelController(devConf.Key, devConf.Name, Global.ControlSystem, buttons); + DeviceManager.AddDevice(tpController); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Unable to deserialize buttons collection for device: {0}", devConf.Key); + } + + } + else + { + Debug.Console(2, "************Processor is not DMPS type***************"); + } + + + + continue; + } + + // Try local factories first + IKeyed newDev = null; + + if (newDev == null) + newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); + + if (newDev != null) + DeviceManager.AddDevice(newDev); + else + Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e); + } + } + Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded."); + + } + + + /// + /// Helper method to load tie lines. This should run after devices have loaded + /// + public void LoadTieLines() + { + // In the future, we can't necessarily just clear here because devices + // might be making their own internal sources/tie lines + + var tlc = TieLineCollection.Default; + //tlc.Clear(); + if (ConfigReader.ConfigObject.TieLines == null) + { + return; + } + + foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines) + { + var newTL = tieLineConfig.GetTieLine(); + if (newTL != null) + tlc.Add(newTL); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Tie Lines Loaded."); + + } + + /// + /// Reads all rooms from config and adds them to DeviceManager + /// + public void LoadRooms() + { + if (ConfigReader.ConfigObject.Rooms == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Configuration contains no rooms - Is this intentional? This may be a valid configuration."); + return; + } + + foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) + { + var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase; + if (room == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key);' + return; + } + + var huddleRoom = room as EssentialsHuddleSpaceRoom; + var vtcRoom = room as EssentialsHuddleVtc1Room; + + if (huddleRoom != null) + { + DeviceManager.AddDevice(huddleRoom); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); + + CreateMobileControlBridge(room); + } + else if (room is EssentialsHuddleVtc1Room) + { + DeviceManager.AddDevice(room); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); + // Mobile Control bridge + var bridge = new MobileControlEssentialsHuddleSpaceRoomBridge(huddleRoom); + AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present + DeviceManager.AddDevice(bridge); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); + + CreateMobileControlBridge(room); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion"); + DeviceManager.AddDevice(room); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController(vtcRoom, 0xf1)); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge..."); + // Mobile Control bridge + var bridge = new MobileControlEssentialsHuddleSpaceRoomBridge(room); + AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present + DeviceManager.AddDevice(bridge); + continue; + } + else + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Notice: Cannot create room from config, key '{0}' - Is this intentional? This may be a valid configuration.", roomConfig.Key); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded."); + + } + + private static void CreateMobileControlBridge(EssentialsRoomBase room) + { + var mobileControl = GetMobileControlDevice(); + + if (mobileControl == null) return; + + mobileControl.CreateMobileControlRoomBridge(room, mobileControl); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added..."); + } + + private static IMobileControl GetMobileControlDevice() + { + var mobileControlList = DeviceManager.AllDevices.OfType().ToList(); + + if (mobileControlList.Count > 1) + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, + "Multiple instances of Mobile Control Server found."); + + return null; + } + + if (mobileControlList.Count > 0) + { + return mobileControlList[0]; + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control not enabled for this system"); + return null; + } + + /// + /// Fires up a logo server if not already running + /// + void LoadLogoServer() + { + if (ConfigReader.ConfigObject.Rooms == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "No rooms configured. Bypassing Logo server startup."); + return; + } + + if ( + !ConfigReader.ConfigObject.Rooms.Any( + CheckRoomConfig)) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "No rooms configured to use system Logo server. Bypassing Logo server startup"); + return; + } + + try + { + LogoServer = new HttpLogoServer(8080, Global.DirectorySeparator + "html" + Global.DirectorySeparator + "logo"); + } + catch (Exception) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program"); + } + } + + private bool CheckRoomConfig(DeviceConfig c) + { + string logoDark = null; + string logoLight = null; + string logo = null; + + if (c.Properties["logoDark"] != null) + { + logoDark = c.Properties["logoDark"].Value("type"); + } + + if (c.Properties["logoLight"] != null) + { + logoLight = c.Properties["logoLight"].Value("type"); + } + + if (c.Properties["logo"] != null) + { + logo = c.Properties["logo"].Value("type"); + } + + return ((logoDark != null && logoDark == "system") || + (logoLight != null && logoLight == "system") || (logo != null && logo == "system")); + } + } +} diff --git a/PepperDashEssentials/Devices/Amplifier.cs b/PepperDashEssentials/Devices/Amplifier.cs index b2725109..dc35de6b 100644 --- a/PepperDashEssentials/Devices/Amplifier.cs +++ b/PepperDashEssentials/Devices/Amplifier.cs @@ -11,7 +11,7 @@ using PepperDash.Essentials.Core.Routing; namespace PepperDash.Essentials { - public class Amplifier : EssentialsDevice, IRoutingSinkNoSwitching + public class Amplifier : EssentialsDevice, IRoutingSink { public event SourceInfoChangeHandler CurrentSourceChange; diff --git a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs index 722698a7..f0fa9ec4 100644 --- a/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs +++ b/PepperDashEssentials/Fusion/EssentialsHuddleVtc1FusionController.cs @@ -303,7 +303,7 @@ namespace PepperDash.Essentials.Fusion return; } - var defaultDisplay = essentialsHuddleVtc1Room.DefaultDisplay as DisplayBase; + var defaultDisplay = essentialsHuddleVtc1Room.DefaultDisplay as TwoWayDisplayBase; if (defaultDisplay == null) { Debug.Console(1, this, "Cannot link null display to Fusion because default display is null"); @@ -373,7 +373,7 @@ namespace PepperDash.Essentials.Fusion } } - protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display) + protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, TwoWayDisplayBase display) { var displayName = string.Format("Display {0} - ", displayIndex); diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index 2c71efe6..47b78c79 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -129,23 +129,10 @@ + - - - - - - - - - - - - - - diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs index 459e709b..12d3822d 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddle/EssentialsHuddlePanelAvFunctionsDriver.cs @@ -22,6 +22,11 @@ namespace PepperDash.Essentials PresentationMode, AudioSetup } + /// + /// The parent driver for this + /// + public PanelDriverBase Parent { get; private set; } + public uint StartPageVisibleJoin { get; private set; } @@ -214,14 +219,25 @@ namespace PepperDash.Essentials switch (_config.HeaderStyle.ToLower()) { case CrestronTouchpanelPropertiesConfig.Habanero: - TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => - PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible)); + TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, (() => + { + if (CurrentRoom.IsMobileControlEnabled) + { + Debug.Console(1, "Showing Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible); + } + else + { + Debug.Console(1, "Showing Non Mobile Control Header Info"); + PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible); + } + })); break; case CrestronTouchpanelPropertiesConfig.Verbose: break; } - if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero) + if (_config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Habanero) { TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => { @@ -237,7 +253,7 @@ namespace PepperDash.Essentials } }); } - else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) + else if (_config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) { TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => { @@ -254,9 +270,9 @@ namespace PepperDash.Essentials }); } - TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime); - TriList.SetBool(UIBoolJoin.DateOnlyVisible, Config.ShowDate && !Config.ShowTime); - TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !Config.ShowDate && Config.ShowTime); + TriList.SetBool(UIBoolJoin.DateAndTimeVisible, _config.ShowDate && _config.ShowTime); + TriList.SetBool(UIBoolJoin.DateOnlyVisible, _config.ShowDate && !_config.ShowTime); + TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !_config.ShowDate && _config.ShowTime); TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true); TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = true; @@ -343,8 +359,8 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, true); - TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _CurrentRoom.LogoUrlLightBkgnd); - TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _CurrentRoom.LogoUrlDarkBkgnd); + TriList.SetString(UIStringJoin.LogoUrlLightBkgnd, _currentRoom.LogoUrlLightBkgnd); + TriList.SetString(UIStringJoin.LogoUrlDarkBkgnd, _currentRoom.LogoUrlDarkBkgnd); } } @@ -854,8 +870,8 @@ namespace PepperDash.Essentials if (_currentRoom == room) return; // Disconnect current (probably never called) - if (_CurrentRoom != null) - _CurrentRoom.ConfigChanged -= room_ConfigChanged; + if (_currentRoom != null) + _currentRoom.ConfigChanged -= room_ConfigChanged; room.ConfigChanged -= room_ConfigChanged; room.ConfigChanged += room_ConfigChanged; @@ -865,8 +881,8 @@ namespace PepperDash.Essentials StartPageVisibleJoin = UIBoolJoin.StartMCPageVisible; UpdateMCJoins(room); - if (_CurrentRoom != null) - _CurrentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; + if (_currentRoom != null) + _currentRoom.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; room.MobileControlRoomBridge.UserCodeChanged -= MobileControlRoomBridge_UserCodeChanged; room.MobileControlRoomBridge.UserCodeChanged += MobileControlRoomBridge_UserCodeChanged; @@ -881,7 +897,7 @@ namespace PepperDash.Essentials void MobileControlRoomBridge_UserCodeChanged(object sender, EventArgs e) { - UpdateMCJoins(_CurrentRoom); + UpdateMCJoins(_currentRoom); } void UpdateMCJoins(EssentialsHuddleSpaceRoom room) diff --git a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs index cb52bf7c..1f692746 100644 --- a/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs +++ b/PepperDashEssentials/UIDrivers/EssentialsHuddleVTC/EssentialsHuddleVtc1PanelAvFunctionsDriver.cs @@ -1,17 +1,18 @@ using System; -using System.Collections.Generic; using System.Linq; +using System.Collections.Generic; using Crestron.SimplSharp; using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.UI; + using PepperDash.Core; using PepperDash.Essentials.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Devices.Codec; -using PepperDash.Essentials.Core.Devices.VideoCodec; +using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.PageManagers; -using PepperDash.Essentials.Core.Touchpanels.Keyboards; -using PepperDash.Essentials.UIDrivers; -using PepperDash.Essentials.UIDrivers.VC; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec; namespace PepperDash.Essentials { @@ -20,14 +21,11 @@ namespace PepperDash.Essentials /// public class EssentialsHuddleVtc1PanelAvFunctionsDriver : PanelDriverBase, IAVWithVCDriver { - #region UiDisplayMode enum + CrestronTouchpanelPropertiesConfig Config; public enum UiDisplayMode { - Presentation, - AudioSetup, - Call, - Start + Presentation, AudioSetup, Call, Start } public uint StartPageVisibleJoin { get; private set; } @@ -38,143 +36,6 @@ namespace PepperDash.Essentials /// public bool ShowVolumeGauge { get; set; } - /// - /// Smart Object 15022 - /// - private readonly SubpageReferenceList _activityFooterSrl; - - /// - /// For hitting feedbacks - /// - private readonly BoolInputSig _callButtonSig; - - private readonly List _currentDisplayModeSigsInUse = new List(); - - private readonly BoolInputSig _endMeetingButtonSig; - - /// - /// The list of buttons on the header. Managed with visibility only - /// - //SmartObjectHeaderButtonList HeaderButtonsList; - /// - /// The AV page mangagers that have been used, to keep them alive for later - /// - private readonly Dictionary _pageManagers = new Dictionary(); - - /// - /// The parent driver for this - /// - private readonly PanelDriverBase _parent; - - private readonly BoolInputSig _shareButtonSig; - - //// Important smart objects - - /// - /// Smart Object 3200 - /// - private readonly SubpageReferenceList _sourceStagingSrl; - - private readonly CrestronTouchpanelPropertiesConfig _config; - - /// - /// Interlocks the various call-related subpages - /// - private JoinedSigInterlock _callPagesInterlock; - - private BoolFeedback _callSharingInfoVisibleFeedback; - - /// - /// All children attached to this driver. For hiding and showing as a group. - /// - private List _childDrivers = new List(); - - /// - /// The mode showing. Presentation or call. - /// - private UiDisplayMode _currentMode = UiDisplayMode.Start; - - /// - /// Current page manager running for a source - /// - private PageManager _currentSourcePageManager; - - /// - /// Tracks the last meeting that was cancelled - /// - private string _lastMeetingDismissedId; - - private CTimer _nextMeetingTimer; - - /// - /// - /// - private ModalDialog _powerDownModal; - - /// - /// Will auto-timeout a power off - /// - private CTimer _powerOffTimer; - - /// - /// Controls timeout of notification ribbon timer - /// - private CTimer _ribbonTimer; - - /// - /// Interlock for various source, camera, call control bars. The bar above the activity footer. This is also - /// used to show start page - /// - private JoinedSigInterlock _stagingBarInterlock; - - /// - /// The Video codec driver - /// - private EssentialsVideoCodecUiDriver _vcDriver; - - private EssentialsHuddleVtc1Room _currentRoom; - - private EssentialsHuddleTechPageDriver _TechDriver; - - /// - /// Constructor - /// - public EssentialsHuddleVtc1PanelAvFunctionsDriver(PanelDriverBase parent, - CrestronTouchpanelPropertiesConfig config) - : base(parent.TriList) - { - _config = config; - _parent = parent; - - PopupInterlock = new JoinedSigInterlock(TriList); - _stagingBarInterlock = new JoinedSigInterlock(TriList); - _callPagesInterlock = new JoinedSigInterlock(TriList); - - _sourceStagingSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.SourceStagingSRL, 3, 3, 3); - - _activityFooterSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.ActivityFooterSRL, 3, 3, 3); - _callButtonSig = _activityFooterSrl.BoolInputSig(2, 1); - _shareButtonSig = _activityFooterSrl.BoolInputSig(1, 1); - _endMeetingButtonSig = _activityFooterSrl.BoolInputSig(3, 1); - - MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5); - - - // buttons are added in SetCurrentRoom - //HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]); - - SetupActivityFooterWhenRoomOff(); - - ShowVolumeGauge = true; - Keyboard = new HabaneroKeyboardController(TriList); - } - - /// - /// Whether volume ramping from this panel will show the volume - /// gauge popup. - /// - public bool ShowVolumeGauge { get; set; } - /// /// /// @@ -185,139 +46,184 @@ namespace PepperDash.Essentials /// public string DefaultRoomKey { get; set; } - /// - /// The driver for the tech page. Lazy getter for memory usage - /// - private EssentialsHuddleTechPageDriver TechDriver - { - get - { - return _TechDriver ?? (_TechDriver = new EssentialsHuddleTechPageDriver(TriList, - CurrentRoom.PropertiesConfig.Tech)); - } - } - - #region IAVWithVCDriver Members /// /// /// public EssentialsHuddleVtc1Room CurrentRoom { - get { return _currentRoom; } - set { SetCurrentRoom(value); } + get { return _CurrentRoom; } + set + { + SetCurrentRoom(value); + } } + EssentialsHuddleVtc1Room _CurrentRoom; + + /// + /// For hitting feedbacks + /// + BoolInputSig CallButtonSig; + BoolInputSig ShareButtonSig; + BoolInputSig EndMeetingButtonSig; + + BoolFeedback CallSharingInfoVisibleFeedback; + + /// + /// The parent driver for this + /// + public PanelDriverBase Parent { get; private set; } + + /// + /// All children attached to this driver. For hiding and showing as a group. + /// + List ChildDrivers = new List(); + + List CurrentDisplayModeSigsInUse = new List(); + + //// Important smart objects + + /// + /// Smart Object 3200 + /// + SubpageReferenceList SourceStagingSrl; + + /// + /// Smart Object 15022 + /// + SubpageReferenceList ActivityFooterSrl; /// /// /// public SubpageReferenceList MeetingOrContactMethodModalSrl { get; set; } + /// + /// The list of buttons on the header. Managed with visibility only + /// + //SmartObjectHeaderButtonList HeaderButtonsList; + + /// + /// The AV page mangagers that have been used, to keep them alive for later + /// + Dictionary PageManagers = new Dictionary(); + + /// + /// Current page manager running for a source + /// + PageManager CurrentSourcePageManager; + + /// + /// Will auto-timeout a power off + /// + CTimer PowerOffTimer; + + /// + /// + /// + ModalDialog PowerDownModal; + /// /// /// //ModalDialog WarmingCoolingModal; + /// /// Represents /// public JoinedSigInterlock PopupInterlock { get; private set; } + /// + /// Interlock for various source, camera, call control bars. The bar above the activity footer. This is also + /// used to show start page + /// + JoinedSigInterlock StagingBarInterlock; + + /// + /// Interlocks the various call-related subpages + /// + JoinedSigInterlock CallPagesInterlock; + + /// + /// The Video codec driver + /// + PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver VCDriver; + + /// + /// The driver for the tech page. Lazy getter for memory usage + /// + PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver TechDriver + { + get + { + if (_TechDriver == null) + _TechDriver = new PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver(TriList, CurrentRoom.PropertiesConfig.Tech); + return _TechDriver; + } + } + PepperDash.Essentials.UIDrivers.EssentialsHuddleTechPageDriver _TechDriver; + + /// + /// Controls timeout of notification ribbon timer + /// + CTimer RibbonTimer; + /// /// The keyboard /// - public HabaneroKeyboardController Keyboard { get; private set; - } + public PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; private set; } /// - /// Reveals a message on the notification ribbon until cleared + /// The mode showing. Presentation or call. /// - /// Text to display - /// Time in ms to display. 0 to keep on screen - public void ShowNotificationRibbon(string message, int timeout) - { - TriList.SetString(UIStringJoin.NotificationRibbonText, message); - TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, true); - if (timeout > 0) - { - if (_ribbonTimer != null) - { - _ribbonTimer.Stop(); - } - _ribbonTimer = new CTimer(o => - { - TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false); - _ribbonTimer = null; - }, timeout); - } - } + UiDisplayMode CurrentMode = UiDisplayMode.Start; + + CTimer NextMeetingTimer; /// - /// Hides the notification ribbon + /// Tracks the last meeting that was cancelled /// - public void HideNotificationRibbon() - { - TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false); - if (_ribbonTimer != null) - { - _ribbonTimer.Stop(); - _ribbonTimer = null; - } - } + string LastMeetingDismissedId; /// - /// Reveals the tech page and puts away anything that's in the way. + /// Constructor /// - public void ShowTech() + public EssentialsHuddleVtc1PanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config) + : base(parent.TriList) { - PopupInterlock.HideAndClear(); - TechDriver.Show(); - } + Config = config; + Parent = parent; - /// - /// - /// - public void ActivityCallButtonPressed() - { - if (_vcDriver.IsVisible) - { - return; - } - HideLogo(); - HideNextMeetingPopup(); - TriList.SetBool(UIBoolJoin.StartPageVisible, false); - TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); - TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); - if (_currentSourcePageManager != null) - { - _currentSourcePageManager.Hide(); - } - PowerOnFromCall(); - _currentMode = UiDisplayMode.Call; - SetActivityFooterFeedbacks(); - _vcDriver.Show(); - } + PopupInterlock = new JoinedSigInterlock(TriList); + StagingBarInterlock = new JoinedSigInterlock(TriList); + CallPagesInterlock = new JoinedSigInterlock(TriList); - /// - /// Puts away modals and things that might be up when call comes in - /// - public void PrepareForCodecIncomingCall() - { - if (_powerDownModal != null && _powerDownModal.ModalIsVisible) - { - _powerDownModal.CancelDialog(); - } - PopupInterlock.Hide(); - } + SourceStagingSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.SourceStagingSRL, 3, 3, 3); - #endregion + ActivityFooterSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.ActivityFooterSRL, 3, 3, 3); + CallButtonSig = ActivityFooterSrl.BoolInputSig(2, 1); + ShareButtonSig = ActivityFooterSrl.BoolInputSig(1, 1); + EndMeetingButtonSig = ActivityFooterSrl.BoolInputSig(3, 1); + + MeetingOrContactMethodModalSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.MeetingListSRL, 3, 3, 5); + + + // buttons are added in SetCurrentRoom + //HeaderButtonsList = new SmartObjectHeaderButtonList(TriList.SmartObjects[UISmartObjectJoin.HeaderButtonList]); + + SetupActivityFooterWhenRoomOff(); + + ShowVolumeGauge = true; + Keyboard = new PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController(TriList); + } /// /// Add a video codec driver to this /// /// - public void SetVideoCodecDriver(EssentialsVideoCodecUiDriver vcd) + public void SetVideoCodecDriver(PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver vcd) { - _vcDriver = vcd; + VCDriver = vcd; } /// @@ -339,17 +245,17 @@ namespace PepperDash.Essentials { if (CurrentRoom.IsMobileControlEnabled) { - Debug.Console(1, "Showing Mobile Control Header Info"); + Debug.Console(1, "Showing Mobile Control Header Info"); PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoMCPageVisible); } else { - Debug.Console(1, "Showing Non Mobile Control Header Info"); + Debug.Console(1, "Showing Non Mobile Control Header Info"); PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderInfoPageVisible); } }); } - else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) + else if (Config.HeaderStyle.ToLower() == CrestronTouchpanelPropertiesConfig.Verbose) { TriList.SetSigFalseAction(UIBoolJoin.HeaderRoomButtonPress, () => { @@ -366,9 +272,9 @@ namespace PepperDash.Essentials }); } - TriList.SetBool(UIBoolJoin.DateAndTimeVisible, _config.ShowDate && _config.ShowTime); - TriList.SetBool(UIBoolJoin.DateOnlyVisible, _config.ShowDate && !_config.ShowTime); - TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !_config.ShowDate && _config.ShowTime); + TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime); + TriList.SetBool(UIBoolJoin.DateOnlyVisible, Config.ShowDate && !Config.ShowTime); + TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !Config.ShowDate && Config.ShowTime); TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true); @@ -376,8 +282,7 @@ namespace PepperDash.Essentials // Privacy mute button TriList.SetSigFalseAction(UIBoolJoin.Volume1SpeechMutePressAndFB, CurrentRoom.PrivacyModeToggle); - CurrentRoom.PrivacyModeIsOnFeedback.LinkInputSig( - TriList.BooleanInput[UIBoolJoin.Volume1SpeechMutePressAndFB]); + CurrentRoom.PrivacyModeIsOnFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.Volume1SpeechMutePressAndFB]); // Default to showing rooms/sources now. if (CurrentRoom.OnFeedback.BoolValue) @@ -430,23 +335,18 @@ namespace PepperDash.Essentials { TriList.SetBool(UIBoolJoin.CallEndAllConfirmVisible, true); if (PopupInterlock.CurrentJoin == UIBoolJoin.HeaderActiveCallsListVisible) - { PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible); - } else { - var videoCodecBase = CurrentRoom.ScheduleSource as VideoCodecBase; - if (videoCodecBase != null && videoCodecBase.IsInCall) - { + if ((CurrentRoom.ScheduleSource as VideoCodecBase).IsInCall) PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HeaderActiveCallsListVisible); - } } } /// /// /// - private void ShowLogo() + void ShowLogo() { if (CurrentRoom.LogoUrlLightBkgnd == null) { @@ -465,7 +365,7 @@ namespace PepperDash.Essentials /// /// /// - private void HideLogo() + void HideLogo() { TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false); TriList.SetBool(UIBoolJoin.LogoUrlVisible, false); @@ -482,27 +382,59 @@ namespace PepperDash.Essentials TriList.BooleanInput[StartPageVisibleJoin].BoolValue = false; TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; - if (_nextMeetingTimer != null) - { - _nextMeetingTimer.Stop(); - } + if (NextMeetingTimer != null) + NextMeetingTimer.Stop(); HideNextMeetingPopup(); base.Hide(); } - private void SetupNextMeetingTimer() + /// + /// Reveals a message on the notification ribbon until cleared + /// + /// Text to display + /// Time in ms to display. 0 to keep on screen + public void ShowNotificationRibbon(string message, int timeout) + { + TriList.SetString(UIStringJoin.NotificationRibbonText, message); + TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, true); + if (timeout > 0) + { + if (RibbonTimer != null) + RibbonTimer.Stop(); + RibbonTimer = new CTimer(o => + { + TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false); + RibbonTimer = null; + }, timeout); + } + } + + /// + /// Hides the notification ribbon + /// + public void HideNotificationRibbon() + { + TriList.SetBool(UIBoolJoin.NotificationRibbonVisible, false); + if (RibbonTimer != null) + { + RibbonTimer.Stop(); + RibbonTimer = null; + } + } + + void SetupNextMeetingTimer() { var ss = CurrentRoom.ScheduleSource; if (ss != null) { - _nextMeetingTimer = new CTimer(o => ShowNextMeetingTimerCallback(), null, 0, 60000); + NextMeetingTimer = new CTimer(o => ShowNextMeetingTimerCallback(), null, 0, 60000); } } /// /// /// - private void ShowNextMeetingTimerCallback() + void ShowNextMeetingTimerCallback() { // Every 60 seconds, refresh the calendar RefreshMeetingsList(); @@ -516,10 +448,10 @@ namespace PepperDash.Essentials // If the room is on, and the meeting is joinable // and the LastMeetingDismissed != this meeting - var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == _lastMeetingDismissedId); + var lastMeetingDismissed = meetings.FirstOrDefault(m => m.Id == LastMeetingDismissedId); Debug.Console(0, "*#* Room on: {0}, lastMeetingDismissedId: {1} {2} *#*", CurrentRoom.OnFeedback.BoolValue, - _lastMeetingDismissedId, + LastMeetingDismissedId, lastMeetingDismissed != null ? lastMeetingDismissed.StartTime.ToShortTimeString() : ""); var meeting = meetings.LastOrDefault(m => m.Joinable); @@ -529,7 +461,7 @@ namespace PepperDash.Essentials return; } - _lastMeetingDismissedId = null; + LastMeetingDismissedId = null; // Clear the popup when we run out of meetings if (meeting == null) { @@ -561,22 +493,16 @@ namespace PepperDash.Essentials // indexOf = 3, 4 meetings : if (indexOfNext < meetings.Count) - { TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, meetings[indexOfNext].StartTime.ToShortTimeString()); - } else - { TriList.SetString(UIStringJoin.NextMeetingFollowingMeetingText, "No more meetings today"); - } TriList.SetSigFalseAction(UIBoolJoin.NextMeetingModalClosePress, () => { // Mark the meeting to not re-harass the user if (CurrentRoom.OnFeedback.BoolValue) - { - _lastMeetingDismissedId = meeting.Id; - } + LastMeetingDismissedId = meeting.Id; HideNextMeetingPopup(); }); @@ -588,9 +514,10 @@ namespace PepperDash.Essentials /// /// /// - private void HideNextMeetingPopup() + void HideNextMeetingPopup() { TriList.SetBool(UIBoolJoin.NextMeetingModalVisible, false); + } /// @@ -605,7 +532,7 @@ namespace PepperDash.Essentials /// /// Dials a meeting after turning on room (if necessary) /// - private void RoomOnAndDialMeeting(Meeting meeting) + void RoomOnAndDialMeeting(Meeting meeting) { Action dialAction = () => { @@ -613,13 +540,11 @@ namespace PepperDash.Essentials if (d != null) { d.Dial(meeting); - _lastMeetingDismissedId = meeting.Id; // To prevent prompts for already-joined call + LastMeetingDismissedId = meeting.Id; // To prevent prompts for already-joined call } }; if (CurrentRoom.OnFeedback.BoolValue) - { dialAction(); - } else { // Rig a one-time handler to catch when the room is warmed and then dial call @@ -637,29 +562,26 @@ namespace PepperDash.Essentials } } + /// + /// Reveals the tech page and puts away anything that's in the way. + /// + public void ShowTech() + { + PopupInterlock.HideAndClear(); + TechDriver.Show(); + } + /// /// When the room is off, set the footer SRL /// - private void SetupActivityFooterWhenRoomOff() + void SetupActivityFooterWhenRoomOff() { - _activityFooterSrl.Clear(); - _activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, _activityFooterSrl, 0, - b => - { - if (!b) - { - ActivityShareButtonPressed(); - } - })); - _activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, _activityFooterSrl, 3, - b => - { - if (!b) - { - ActivityCallButtonPressed(); - } - })); - _activityFooterSrl.Count = 2; + ActivityFooterSrl.Clear(); + ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0, + b => { if (!b) ActivityShareButtonPressed(); })); + ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl, 3, + b => { if (!b) ActivityCallButtonPressed(); })); + ActivityFooterSrl.Count = 2; TriList.SetUshort(UIUshortJoin.PresentationStagingCaretMode, 1); // right one slot TriList.SetUshort(UIUshortJoin.CallStagingCaretMode, 5); // left one slot } @@ -667,34 +589,16 @@ namespace PepperDash.Essentials /// /// Sets up the footer SRL for when the room is on /// - private void SetupActivityFooterWhenRoomOn() + void SetupActivityFooterWhenRoomOn() { - _activityFooterSrl.Clear(); - _activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, _activityFooterSrl, 0, - b => - { - if (!b) - { - ActivityShareButtonPressed(); - } - })); - _activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, _activityFooterSrl, 3, - b => - { - if (!b) - { - ActivityCallButtonPressed(); - } - })); - _activityFooterSrl.AddItem(new SubpageReferenceListActivityItem(3, _activityFooterSrl, 4, - b => - { - if (!b) - { - EndMeetingPress(); - } - })); - _activityFooterSrl.Count = 3; + ActivityFooterSrl.Clear(); + ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0, + b => { if (!b) ActivityShareButtonPressed(); })); + ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl, 3, + b => { if (!b) ActivityCallButtonPressed(); })); + ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(3, ActivityFooterSrl, 4, + b => { if (!b) EndMeetingPress(); })); + ActivityFooterSrl.Count = 3; TriList.SetUshort(UIUshortJoin.PresentationStagingCaretMode, 2); // center TriList.SetUshort(UIUshortJoin.CallStagingCaretMode, 0); // left -2 } @@ -702,11 +606,11 @@ namespace PepperDash.Essentials /// /// Single point call for setting the feedbacks on the activity buttons /// - private void SetActivityFooterFeedbacks() + void SetActivityFooterFeedbacks() { - CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call + CallButtonSig.BoolValue = CurrentMode == UiDisplayMode.Call && CurrentRoom.ShutdownType == eShutdownType.None; - ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation + ShareButtonSig.BoolValue = CurrentMode == UiDisplayMode.Presentation && CurrentRoom.ShutdownType == eShutdownType.None; EndMeetingButtonSig.BoolValue = CurrentRoom.ShutdownType != eShutdownType.None; } @@ -719,13 +623,13 @@ namespace PepperDash.Essentials if (VCDriver.IsVisible) return; HideLogo(); - HideNextMeetingPopup(); + HideNextMeetingPopup(); TriList.SetBool(StartPageVisibleJoin, false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false); TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); if (CurrentSourcePageManager != null) CurrentSourcePageManager.Hide(); - PowerOnFromCall(); + PowerOnFromCall(); CurrentMode = UiDisplayMode.Call; SetActivityFooterFeedbacks(); VCDriver.Show(); @@ -734,15 +638,13 @@ namespace PepperDash.Essentials /// /// Attached to activity list share button /// - private void ActivityShareButtonPressed() + void ActivityShareButtonPressed() { SetupSourceList(); - if (_vcDriver.IsVisible) - { - _vcDriver.Hide(); - } + if (VCDriver.IsVisible) + VCDriver.Hide(); HideNextMeetingPopup(); - TriList.SetBool(UIBoolJoin.StartPageVisible, false); + TriList.SetBool(StartPageVisibleJoin, false); TriList.SetBool(UIBoolJoin.CallStagingBarVisible, false); TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true); // Run default source when room is off and share is pressed @@ -752,24 +654,17 @@ namespace PepperDash.Essentials { // If there's no default, show UI elements if (!CurrentRoom.RunDefaultPresentRoute()) - { TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); - } } } else // room is on show what's active or select a source if nothing is yet active { - if (CurrentRoom.CurrentSourceInfo == null || - CurrentRoom.CurrentSourceInfoKey == EssentialsHuddleVtc1Room.DefaultCodecRouteString) - { + if (CurrentRoom.CurrentSourceInfo == null || CurrentRoom.CurrentSourceInfoKey == EssentialsHuddleVtc1Room.DefaultCodecRouteString) TriList.SetBool(UIBoolJoin.SelectASourceVisible, true); - } - else if (_currentSourcePageManager != null) - { - _currentSourcePageManager.Show(); - } + else if (CurrentSourcePageManager != null) + CurrentSourcePageManager.Show(); } - _currentMode = UiDisplayMode.Presentation; + CurrentMode = UiDisplayMode.Presentation; SetupSourceList(); SetActivityFooterFeedbacks(); } @@ -777,7 +672,7 @@ namespace PepperDash.Essentials /// /// Powers up the system to the codec route, if not already on. /// - private void PowerOnFromCall() + void PowerOnFromCall() { if (!CurrentRoom.OnFeedback.BoolValue) { @@ -788,36 +683,30 @@ namespace PepperDash.Essentials /// /// Shows all sigs that are in CurrentDisplayModeSigsInUse /// - private void ShowCurrentDisplayModeSigsInUse() + void ShowCurrentDisplayModeSigsInUse() { - foreach (var sig in _currentDisplayModeSigsInUse) - { + foreach (var sig in CurrentDisplayModeSigsInUse) sig.BoolValue = true; - } } /// /// Hides all CurrentDisplayModeSigsInUse sigs and clears the array /// - private void HideAndClearCurrentDisplayModeSigsInUse() + void HideAndClearCurrentDisplayModeSigsInUse() { - foreach (var sig in _currentDisplayModeSigsInUse) - { + foreach (var sig in CurrentDisplayModeSigsInUse) sig.BoolValue = false; - } - _currentDisplayModeSigsInUse.Clear(); + CurrentDisplayModeSigsInUse.Clear(); } /// /// Loads the appropriate Sigs into CurrentDisplayModeSigsInUse and shows them /// - private void ShowCurrentSource() + void ShowCurrentSource() { if (CurrentRoom.CurrentSourceInfo == null) - { return; - } if (CurrentRoom.CurrentSourceInfo.SourceDevice == null) { @@ -826,35 +715,25 @@ namespace PepperDash.Essentials } var uiDev = CurrentRoom.CurrentSourceInfo.SourceDevice as IUiDisplayInfo; + PageManager pm = null; // If we need a page manager, get an appropriate one - if (uiDev == null) + if (uiDev != null) { - return; - } - - TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); - // Got an existing page manager, get it - PageManager pm; - if (_pageManagers.ContainsKey(uiDev)) - { - pm = _pageManagers[uiDev]; - } + TriList.SetBool(UIBoolJoin.SelectASourceVisible, false); + // Got an existing page manager, get it + if (PageManagers.ContainsKey(uiDev)) + pm = PageManagers[uiDev]; // Otherwise make an apporiate one - else if (uiDev is ISetTopBoxControls) - { - pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList); + else if (uiDev is ISetTopBoxControls) + pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList); + else if (uiDev is IDiscPlayerControls) + pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList); + else + pm = new DefaultPageManager(uiDev, TriList); + PageManagers[uiDev] = pm; + CurrentSourcePageManager = pm; + pm.Show(); } - else if (uiDev is IDiscPlayerControls) - { - pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList); - } - else - { - pm = new DefaultPageManager(uiDev, TriList); - } - _pageManagers[uiDev] = pm; - _currentSourcePageManager = pm; - pm.Show(); } /// @@ -862,10 +741,10 @@ namespace PepperDash.Essentials /// to change to the proper screen. /// /// The key name of the route to run - private void UiSelectSource(string key) + void UiSelectSource(string key) { // Run the route and when it calls back, show the source - CurrentRoom.RunRouteAction(key, () => { }); + CurrentRoom.RunRouteAction(key, new Action(() => { })); } /// @@ -875,19 +754,27 @@ namespace PepperDash.Essentials { if (!CurrentRoom.OnFeedback.BoolValue || CurrentRoom.ShutdownPromptTimer.IsRunningFeedback.BoolValue) - { return; - } CurrentRoom.StartShutdown(eShutdownType.Manual); } + /// + /// Puts away modals and things that might be up when call comes in + /// + public void PrepareForCodecIncomingCall() + { + if (PowerDownModal != null && PowerDownModal.ModalIsVisible) + PowerDownModal.CancelDialog(); + PopupInterlock.Hide(); + } + /// /// /// /// /// - private void ShutdownPromptTimer_HasStarted(object sender, EventArgs e) + void ShutdownPromptTimer_HasStarted(object sender, EventArgs e) { // Do we need to check where the UI is? No? var timer = CurrentRoom.ShutdownPromptTimer; @@ -895,14 +782,12 @@ namespace PepperDash.Essentials if (CurrentRoom.ShutdownType == eShutdownType.Manual || CurrentRoom.ShutdownType == eShutdownType.Vacancy) { - _powerDownModal = new ModalDialog(TriList); + PowerDownModal = new ModalDialog(TriList); var message = string.Format("Meeting will end in {0} seconds", CurrentRoom.ShutdownPromptSeconds); // Attach timer things to modal - CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += - ShutdownPromptTimer_TimeRemainingFeedback_OutputChange; - CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange += - ShutdownPromptTimer_PercentFeedback_OutputChange; + CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange; + CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange += ShutdownPromptTimer_PercentFeedback_OutputChange; // respond to offs by cancelling dialog var onFb = CurrentRoom.OnFeedback; @@ -911,25 +796,20 @@ namespace PepperDash.Essentials { if (!onFb.BoolValue) { - _powerDownModal.HideDialog(); + PowerDownModal.HideDialog(); SetActivityFooterFeedbacks(); onFb.OutputChange -= offHandler; } }; onFb.OutputChange += offHandler; - _powerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, - true, + PowerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true, but => { if (but != 2) // any button except for End cancels - { timer.Cancel(); - } else - { timer.Finish(); - } }); } } @@ -939,13 +819,11 @@ namespace PepperDash.Essentials /// /// /// - private void ShutdownPromptTimer_HasFinished(object sender, EventArgs e) + void ShutdownPromptTimer_HasFinished(object sender, EventArgs e) { SetActivityFooterFeedbacks(); - CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange -= - ShutdownPromptTimer_TimeRemainingFeedback_OutputChange; - CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= - ShutdownPromptTimer_PercentFeedback_OutputChange; + CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange -= ShutdownPromptTimer_TimeRemainingFeedback_OutputChange; + CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange; } /// @@ -953,57 +831,44 @@ namespace PepperDash.Essentials /// /// /// - private void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e) + void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e) { - if (_powerDownModal != null) - { - _powerDownModal.HideDialog(); - } + if (PowerDownModal != null) + PowerDownModal.HideDialog(); SetActivityFooterFeedbacks(); - CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += - ShutdownPromptTimer_TimeRemainingFeedback_OutputChange; - CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= - ShutdownPromptTimer_PercentFeedback_OutputChange; + CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange; + CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange; } /// /// Event handler for countdown timer on power off modal /// - private void ShutdownPromptTimer_TimeRemainingFeedback_OutputChange(object sender, EventArgs e) + void ShutdownPromptTimer_TimeRemainingFeedback_OutputChange(object sender, EventArgs e) { - var stringFeedback = sender as StringFeedback; - if (stringFeedback == null) - { - return; - } - var message = string.Format("Meeting will end in {0} seconds", stringFeedback.StringValue); + + var message = string.Format("Meeting will end in {0} seconds", (sender as StringFeedback).StringValue); TriList.StringInput[ModalDialog.MessageTextJoin].StringValue = message; } /// /// Event handler for percentage on power off countdown /// - private void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e) + void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e) { - var intFeedback = sender as IntFeedback; - if (intFeedback == null) - { - return; - } - var value = (ushort) (intFeedback.UShortValue*65535/100); + var value = (ushort)((sender as IntFeedback).UShortValue * 65535 / 100); TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value; } /// /// /// - private void CancelPowerOffTimer() + void CancelPowerOffTimer() { - if (_powerOffTimer != null) + if (PowerOffTimer != null) { - _powerOffTimer.Stop(); - _powerOffTimer = null; + PowerOffTimer.Stop(); + PowerOffTimer = null; } } @@ -1014,9 +879,7 @@ namespace PepperDash.Essentials public void VolumeUpPress(bool state) { if (CurrentRoom.CurrentVolumeControls != null) - { CurrentRoom.CurrentVolumeControls.VolumeUp(state); - } } /// @@ -1026,91 +889,79 @@ namespace PepperDash.Essentials public void VolumeDownPress(bool state) { if (CurrentRoom.CurrentVolumeControls != null) - { CurrentRoom.CurrentVolumeControls.VolumeDown(state); - } } /// /// Helper for property setter. Sets the panel to the given room, latching up all functionality /// - private void RefreshCurrentRoom(EssentialsHuddleVtc1Room room) + void RefreshCurrentRoom(EssentialsHuddleVtc1Room room) { - if (_currentRoom != null) + + if (_CurrentRoom != null) { // Disconnect current room - _currentRoom.CurrentVolumeDeviceChange -= CurrentRoom_CurrentAudioDeviceChange; + _CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange; ClearAudioDeviceConnections(); - _currentRoom.CurrentSourceChange -= CurrentRoom_SourceInfoChange; - DisconnectSource(_currentRoom.CurrentSourceInfo); - _currentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted; - _currentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished; - _currentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled; + _CurrentRoom.CurrentSourceChange -= this.CurrentRoom_SourceInfoChange; + DisconnectSource(_CurrentRoom.CurrentSourceInfo); + _CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted; + _CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished; + _CurrentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled; - _currentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange; - _currentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange; - _currentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange; - _currentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange; + _CurrentRoom.OnFeedback.OutputChange -= CurrentRoom_OnFeedback_OutputChange; + _CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange; + _CurrentRoom.IsCoolingDownFeedback.OutputChange -= CurrentRoom_IsCoolingDownFeedback_OutputChange; + _CurrentRoom.InCallFeedback.OutputChange -= CurrentRoom_InCallFeedback_OutputChange; } - _currentRoom = room; + _CurrentRoom = room; - if (_currentRoom != null) + if (_CurrentRoom != null) { // get the source list config and set up the source list SetupSourceList(); // Name and logo - TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _currentRoom.Name; + TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name; ShowLogo(); // Shutdown timer - _currentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted; - _currentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished; - _currentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled; + _CurrentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted; + _CurrentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished; + _CurrentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled; // Link up all the change events from the room - _currentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange; + _CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange; CurrentRoom_SyncOnFeedback(); - _currentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange; - _currentRoom.IsCoolingDownFeedback.OutputChange += CurrentRoom_IsCoolingDownFeedback_OutputChange; - _currentRoom.InCallFeedback.OutputChange += CurrentRoom_InCallFeedback_OutputChange; + _CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange; + _CurrentRoom.IsCoolingDownFeedback.OutputChange += CurrentRoom_IsCoolingDownFeedback_OutputChange; + _CurrentRoom.InCallFeedback.OutputChange += CurrentRoom_InCallFeedback_OutputChange; - _currentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange; + _CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange; RefreshAudioDeviceConnections(); - _currentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange; + _CurrentRoom.CurrentSourceChange += CurrentRoom_SourceInfoChange; RefreshSourceInfo(); - if (_currentRoom.VideoCodec is IHasScheduleAwareness) + if (_CurrentRoom.VideoCodec is IHasScheduleAwareness) { - (_currentRoom.VideoCodec as IHasScheduleAwareness).CodecSchedule.MeetingsListHasChanged += - CodecSchedule_MeetingsListHasChanged; + (_CurrentRoom.VideoCodec as IHasScheduleAwareness).CodecSchedule.MeetingsListHasChanged += CodecSchedule_MeetingsListHasChanged; } - _callSharingInfoVisibleFeedback = - new BoolFeedback(() => _currentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue); - _currentRoom.VideoCodec.SharingContentIsOnFeedback.OutputChange += - SharingContentIsOnFeedback_OutputChange; - _callSharingInfoVisibleFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.CallSharedSourceInfoVisible]); + CallSharingInfoVisibleFeedback = new BoolFeedback(() => _CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue); + _CurrentRoom.VideoCodec.SharingContentIsOnFeedback.OutputChange += SharingContentIsOnFeedback_OutputChange; + CallSharingInfoVisibleFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.CallSharedSourceInfoVisible]); SetActiveCallListSharingContentStatus(); - if (_currentRoom != null) - { - _currentRoom.CurrentSourceChange += - CurrentRoom_CurrentSingleSourceChange; - } + if (_CurrentRoom != null) + _CurrentRoom.CurrentSourceChange += new SourceInfoChangeHandler(CurrentRoom_CurrentSingleSourceChange); - TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, - () => _currentRoom.RunRouteAction("codecOsd", _currentRoom.SourceListKey)); + TriList.SetSigFalseAction(UIBoolJoin.CallStopSharingPress, () => _CurrentRoom.RunRouteAction("codecOsd", _CurrentRoom.SourceListKey)); - var essentialsPanelMainInterfaceDriver = _parent as EssentialsPanelMainInterfaceDriver; - if (essentialsPanelMainInterfaceDriver != null) - { - essentialsPanelMainInterfaceDriver.HeaderDriver.SetupHeaderButtons(this, CurrentRoom); - } + (Parent as EssentialsPanelMainInterfaceDriver).HeaderDriver.SetupHeaderButtons(this, CurrentRoom); } else { @@ -1119,15 +970,12 @@ namespace PepperDash.Essentials } } - private void SetCurrentRoom(EssentialsHuddleVtc1Room room) + void SetCurrentRoom(EssentialsHuddleVtc1Room room) { - if (_currentRoom == room) - { - return; - } + if (_CurrentRoom == room) return; // Disconnect current (probably never called) - if(_CurrentRoom != null) + if (_CurrentRoom != null) _CurrentRoom.ConfigChanged -= room_ConfigChanged; room.ConfigChanged -= room_ConfigChanged; @@ -1169,9 +1017,9 @@ namespace PepperDash.Essentials /// /// /// - private void room_ConfigChanged(object sender, EventArgs e) + void room_ConfigChanged(object sender, EventArgs e) { - RefreshCurrentRoom(_currentRoom); + RefreshCurrentRoom(_CurrentRoom); } /// @@ -1179,7 +1027,7 @@ namespace PepperDash.Essentials /// /// /// - private void CurrentRoom_InCallFeedback_OutputChange(object sender, EventArgs e) + void CurrentRoom_InCallFeedback_OutputChange(object sender, EventArgs e) { var inCall = CurrentRoom.InCallFeedback.BoolValue; if (inCall) @@ -1198,46 +1046,46 @@ namespace PepperDash.Essentials /// /// /// - private void SetupSourceList() + void SetupSourceList() { + var inCall = CurrentRoom.InCallFeedback.BoolValue; 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 - _sourceStagingSrl.Clear(); + SourceStagingSrl.Clear(); uint i = 1; // counter for UI list foreach (var kvp in srcList) { var srcConfig = kvp.Value; - Debug.Console(1, "**** {0}, {1}, {2}, {3}, {4}", srcConfig.PreferredName, - srcConfig.IncludeInSourceList, - srcConfig.DisableCodecSharing, inCall, _currentMode); + Debug.Console(1, "**** {0}, {1}, {2}, {3}, {4}", srcConfig.PreferredName, srcConfig.IncludeInSourceList, + srcConfig.DisableCodecSharing, inCall, this.CurrentMode); // Skip sources marked as not included, and filter list of non-sharable sources when in call // or on share screen if (!srcConfig.IncludeInSourceList || (inCall && srcConfig.DisableCodecSharing) - || _currentMode == UiDisplayMode.Call && srcConfig.DisableCodecSharing) + || this.CurrentMode == UiDisplayMode.Call && srcConfig.DisableCodecSharing) { Debug.Console(1, "Skipping {0}", srcConfig.PreferredName); continue; } var routeKey = kvp.Key; - var item = new SubpageReferenceListSourceItem(i++, _sourceStagingSrl, srcConfig, - b => - { - if (!b) - { - UiSelectSource(routeKey); - } - }); - _sourceStagingSrl.AddItem(item); // add to the SRL - item.RegisterForSourceChange(_currentRoom); + var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig, + b => { if (!b) UiSelectSource(routeKey); }); + SourceStagingSrl.AddItem(item); // add to the SRL + item.RegisterForSourceChange(_CurrentRoom); + Debug.Console(1, "**** KEY {0}", kvp.Key); + } - _sourceStagingSrl.Count = (ushort) (i - 1); + SourceStagingSrl.Count = (ushort)(i - 1); } + } /// @@ -1245,7 +1093,7 @@ namespace PepperDash.Essentials /// /// /// - private void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e) + void CodecSchedule_MeetingsListHasChanged(object sender, EventArgs e) { RefreshMeetingsList(); } @@ -1253,15 +1101,13 @@ namespace PepperDash.Essentials /// /// Updates the current shared source label on the call list when the source changes /// + /// /// /// - private void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type) + void CurrentRoom_CurrentSingleSourceChange(SourceListItem info, ChangeType type) { - if (_currentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _currentRoom.CurrentSourceInfo != null) - { - TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = - _currentRoom.CurrentSourceInfo.PreferredName; - } + if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null) + TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = _CurrentRoom.CurrentSourceInfo.PreferredName; } /// @@ -1269,7 +1115,7 @@ namespace PepperDash.Essentials /// /// /// - private void SharingContentIsOnFeedback_OutputChange(object sender, EventArgs e) + void SharingContentIsOnFeedback_OutputChange(object sender, EventArgs e) { SetActiveCallListSharingContentStatus(); } @@ -1277,22 +1123,20 @@ namespace PepperDash.Essentials /// /// Sets the values for the text and button visibilty for the active call list source sharing info /// - private void SetActiveCallListSharingContentStatus() + void SetActiveCallListSharingContentStatus() { - _callSharingInfoVisibleFeedback.FireUpdate(); + CallSharingInfoVisibleFeedback.FireUpdate(); string callListSharedSourceLabel; - if (_currentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _currentRoom.CurrentSourceInfo != null) + if (_CurrentRoom.VideoCodec.SharingContentIsOnFeedback.BoolValue && _CurrentRoom.CurrentSourceInfo != null) { Debug.Console(0, "*#* CurrentRoom.CurrentSourceInfo = {0}", - _currentRoom.CurrentSourceInfo != null ? _currentRoom.CurrentSourceInfo.SourceKey : "Nada!"); - callListSharedSourceLabel = _currentRoom.CurrentSourceInfo.PreferredName; + _CurrentRoom.CurrentSourceInfo != null ? _CurrentRoom.CurrentSourceInfo.SourceKey : "Nada!"); + callListSharedSourceLabel = _CurrentRoom.CurrentSourceInfo.PreferredName; } else - { callListSharedSourceLabel = "None"; - } TriList.StringInput[UIStringJoin.CallSharedSourceNameText].StringValue = callListSharedSourceLabel; } @@ -1300,7 +1144,7 @@ namespace PepperDash.Essentials /// /// /// - private void RefreshMeetingsList() + void RefreshMeetingsList() { // See if this is helpful or if the callback response in the codec class maybe doesn't come it time? // Let's build list from event @@ -1326,21 +1170,18 @@ namespace PepperDash.Essentials ActivityCallButtonPressed(); var d = CurrentRoom.ScheduleSource as VideoCodecBase; if (d != null) - { RoomOnAndDialMeeting(mm); - } }); } MeetingOrContactMethodModalSrl.Count = i; - if (i == 0) // Show item indicating no meetings are booked for rest of day + if (i == 0) // Show item indicating no meetings are booked for rest of day { MeetingOrContactMethodModalSrl.Count = 1; MeetingOrContactMethodModalSrl.StringInputSig(1, 1).StringValue = string.Empty; MeetingOrContactMethodModalSrl.StringInputSig(1, 2).StringValue = string.Empty; - MeetingOrContactMethodModalSrl.StringInputSig(1, 3).StringValue = - "No Meetings are booked for the remainder of the day."; + MeetingOrContactMethodModalSrl.StringInputSig(1, 3).StringValue = "No Meetings are booked for the remainder of the day."; MeetingOrContactMethodModalSrl.StringInputSig(1, 4).StringValue = string.Empty; MeetingOrContactMethodModalSrl.StringInputSig(1, 5).StringValue = string.Empty; } @@ -1349,7 +1190,7 @@ namespace PepperDash.Essentials /// /// For room on/off changes /// - private void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e) + void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e) { CurrentRoom_SyncOnFeedback(); } @@ -1357,9 +1198,9 @@ namespace PepperDash.Essentials /// /// /// - private void CurrentRoom_SyncOnFeedback() + void CurrentRoom_SyncOnFeedback() { - var value = _currentRoom.OnFeedback.BoolValue; + var value = _CurrentRoom.OnFeedback.BoolValue; TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value; TriList.BooleanInput[StartPageVisibleJoin].BoolValue = !value; @@ -1369,28 +1210,27 @@ namespace PepperDash.Essentials SetupActivityFooterWhenRoomOn(); TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = true; + } else { - _currentMode = UiDisplayMode.Start; - if (_vcDriver.IsVisible) - { - _vcDriver.Hide(); - } + CurrentMode = UiDisplayMode.Start; + if (VCDriver.IsVisible) + VCDriver.Hide(); SetupActivityFooterWhenRoomOff(); ShowLogo(); SetActivityFooterFeedbacks(); TriList.BooleanInput[UIBoolJoin.VolumeDualMute1Visible].BoolValue = false; TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false; // Clear this so that the pesky meeting warning can resurface every minute when off - _lastMeetingDismissedId = null; + LastMeetingDismissedId = null; } } /// /// /// - private void CurrentRoom_IsWarmingFeedback_OutputChange(object sender, EventArgs e) + void CurrentRoom_IsWarmingFeedback_OutputChange(object sender, EventArgs e) { if (CurrentRoom.IsWarmingUpFeedback.BoolValue) { @@ -1407,7 +1247,7 @@ namespace PepperDash.Essentials /// /// /// - private void CurrentRoom_IsCoolingDownFeedback_OutputChange(object sender, EventArgs e) + void CurrentRoom_IsCoolingDownFeedback_OutputChange(object sender, EventArgs e) { if (CurrentRoom.IsCoolingDownFeedback.BoolValue) { @@ -1423,131 +1263,105 @@ namespace PepperDash.Essentials /// Hides source for provided source info /// /// - private void DisconnectSource(SourceListItem previousInfo) + void DisconnectSource(SourceListItem previousInfo) { - if (previousInfo == null) - { - return; - } + if (previousInfo == null) return; // Hide whatever is showing if (IsVisible) { - if (_currentSourcePageManager != null) + if (CurrentSourcePageManager != null) { - _currentSourcePageManager.Hide(); - _currentSourcePageManager = null; + CurrentSourcePageManager.Hide(); + CurrentSourcePageManager = null; } } + if (previousInfo == null) return; var previousDev = previousInfo.SourceDevice; // device type interfaces if (previousDev is ISetTopBoxControls) - { (previousDev as ISetTopBoxControls).UnlinkButtons(TriList); - } // common interfaces if (previousDev is IChannel) - { (previousDev as IChannel).UnlinkButtons(TriList); - } if (previousDev is IColor) - { (previousDev as IColor).UnlinkButtons(TriList); - } if (previousDev is IDPad) - { (previousDev as IDPad).UnlinkButtons(TriList); - } if (previousDev is IDvr) - { (previousDev as IDvr).UnlinkButtons(TriList); - } if (previousDev is INumericKeypad) - { (previousDev as INumericKeypad).UnlinkButtons(TriList); if (previousDev is IHasPowerControl) (previousDev as IHasPowerControl).UnlinkButtons(TriList); if (previousDev is ITransport) - { (previousDev as ITransport).UnlinkButtons(TriList); - } } /// /// Refreshes and shows the room's current source /// - private void RefreshSourceInfo() + void RefreshSourceInfo() { var routeInfo = CurrentRoom.CurrentSourceInfo; // This will show off popup too - if (IsVisible && !_vcDriver.IsVisible) - { + if (this.IsVisible && !VCDriver.IsVisible) ShowCurrentSource(); - } - if (routeInfo == null) // || !CurrentRoom.OnFeedback.BoolValue) + if (routeInfo == null)// || !CurrentRoom.OnFeedback.BoolValue) { // Check for power off and insert "Room is off" TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "Room is off"; TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Power"; - Hide(); - _parent.Show(); + this.Hide(); + Parent.Show(); return; } - TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName; - TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank" - - //code that was here was unreachable becuase if we get past the if statement, routeInfo is not null...no third option. + else if (routeInfo != null) + { + TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName; + TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank" + } + else // This never gets hit???!!! + { + TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---"; + TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank"; + } // Connect controls if (routeInfo.SourceDevice != null) - { ConnectControlDeviceMethods(routeInfo.SourceDevice); - } } /// /// Attach the source to the buttons and things /// - private void ConnectControlDeviceMethods(Device dev) + void ConnectControlDeviceMethods(Device dev) { if (dev is ISetTopBoxControls) - { (dev as ISetTopBoxControls).LinkButtons(TriList); - } if (dev is IChannel) - { (dev as IChannel).LinkButtons(TriList); - } if (dev is IColor) - { (dev as IColor).LinkButtons(TriList); - } if (dev is IDPad) - { (dev as IDPad).LinkButtons(TriList); - } if (dev is IDvr) - { (dev as IDvr).LinkButtons(TriList); - } if (dev is INumericKeypad) - { (dev as INumericKeypad).LinkButtons(TriList); if (dev is IHasPowerControl) (dev as IHasPowerControl).LinkButtons(TriList); if (dev is ITransport) - { (dev as ITransport).LinkButtons(TriList); - } } /// /// Detaches the buttons and feedback from the room's current audio device /// - private void ClearAudioDeviceConnections() + void ClearAudioDeviceConnections() { TriList.ClearBoolSigAction(UIBoolJoin.VolumeUpPress); TriList.ClearBoolSigAction(UIBoolJoin.VolumeDownPress); @@ -1565,7 +1379,7 @@ namespace PepperDash.Essentials /// /// Attaches the buttons and feedback to the room's current audio device /// - private void RefreshAudioDeviceConnections() + void RefreshAudioDeviceConnections() { var dev = CurrentRoom.CurrentVolumeControls; if (dev != null) // connect buttons @@ -1577,9 +1391,7 @@ namespace PepperDash.Essentials var fbDev = dev as IBasicVolumeWithFeedback; if (fbDev == null) // this should catch both IBasicVolume and IBasicVolumeWithFeeback - { TriList.UShortInput[UIUshortJoin.VolumeSlider1Value].UShortValue = 0; - } else { // slider @@ -1594,31 +1406,23 @@ namespace PepperDash.Essentials /// /// Handler for when the room's volume control device changes /// - private void CurrentRoom_CurrentAudioDeviceChange(object sender, VolumeDeviceChangeEventArgs args) + void CurrentRoom_CurrentAudioDeviceChange(object sender, VolumeDeviceChangeEventArgs args) { if (args.Type == ChangeType.WillChange) - { ClearAudioDeviceConnections(); - } else // did change - { RefreshAudioDeviceConnections(); - } } /// /// Handles source change /// - private void CurrentRoom_SourceInfoChange(SourceListItem info, ChangeType change) + void CurrentRoom_SourceInfoChange(SourceListItem info, ChangeType change) { if (change == ChangeType.WillChange) - { DisconnectSource(info); - } else - { RefreshSourceInfo(); - } } } @@ -1642,17 +1446,16 @@ namespace PepperDash.Essentials { EssentialsHuddleVtc1Room CurrentRoom { get; } - HabaneroKeyboardController Keyboard { get; } - SubpageReferenceList MeetingOrContactMethodModalSrl { get; } - + PepperDash.Essentials.Core.Touchpanels.Keyboards.HabaneroKeyboardController Keyboard { get; } /// /// Exposes the ability to switch into call mode /// void ActivityCallButtonPressed(); - /// /// Allows the codec to trigger the main UI to clear up if call is coming in. /// void PrepareForCodecIncomingCall(); + + SubpageReferenceList MeetingOrContactMethodModalSrl { get; } } -} \ No newline at end of file +} diff --git a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs index b5ddd149..eef26d87 100644 --- a/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs +++ b/PepperDashEssentials/UIDrivers/VC/EssentialsVideoCodecUiDriver.cs @@ -14,6 +14,8 @@ using PepperDash.Essentials.Core.Devices.VideoCodec; using PepperDash.Essentials.Core.SmartObjects; using PepperDash.Essentials.Core.Touchpanels.Keyboards; using PepperDash.Essentials.Core.Devices.Codec; +using PepperDash.Essentials.Devices.Common.Cameras; +using PepperDash.Essentials.Devices.Common.Codec; using PepperDash.Essentials.Devices.Common.VideoCodec; using PepperDash.Essentials.Devices.Core.VideoCodec; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasCallHistory.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasCallHistory.cs index bb5404d0..87bf718d 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasCallHistory.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasCallHistory.cs @@ -46,6 +46,13 @@ namespace PepperDash.Essentials.Core.Devices.Codec RecentCalls = new List {_listEmptyEntry}; } + public void UpdateRecentCallsList(List entries) + { + RecentCalls = entries; + + OnRecentCallsListChange(); + } + private void OnRecentCallsListChange() { var handler = RecentCallsListHasChanged; diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasScheduleAwareness.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasScheduleAwareness.cs index c1e5a01e..dd67a064 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasScheduleAwareness.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/DeviceTypeInterfaces/Codec/iHasScheduleAwareness.cs @@ -22,24 +22,32 @@ namespace PepperDash.Essentials.Core.Devices.Codec public class CodecScheduleAwareness { - List _Meetings; + List _meetings; public event EventHandler MeetingEventChange; public event EventHandler MeetingsListHasChanged; - /// - /// Setter triggers MeetingsListHasChanged event - /// + private int _meetingWarningMinutes = 5; + + public int MeetingWarningMinutes + { + get { return _meetingWarningMinutes; } + set { _meetingWarningMinutes = value; } + } + + /// + /// Setter triggers MeetingsListHasChanged event + /// public List Meetings { get { - return _Meetings; + return _meetings; } set { - _Meetings = value; + _meetings = value; var handler = MeetingsListHasChanged; if (handler != null) @@ -49,13 +57,20 @@ namespace PepperDash.Essentials.Core.Devices.Codec } } - private CTimer ScheduleChecker; + private CTimer _scheduleChecker; public CodecScheduleAwareness() { Meetings = new List(); - ScheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000); + _scheduleChecker = new CTimer(CheckSchedule, null, 1000, 1000); + } + + public CodecScheduleAwareness(long pollTime) + { + Meetings = new List(); + + _scheduleChecker = new CTimer(CheckSchedule, null, pollTime, pollTime); } private void OnMeetingChange(eMeetingEventChangeType changeType, Meeting meeting) @@ -72,9 +87,9 @@ namespace PepperDash.Essentials.Core.Devices.Codec // Iterate the meeting list and check if any meeting need to do anythingk const double meetingTimeEpsilon = 0.0001; - foreach (Meeting m in Meetings) + foreach (var m in Meetings) { - eMeetingEventChangeType changeType = eMeetingEventChangeType.Unkown; + var changeType = eMeetingEventChangeType.Unkown; if (m.TimeToMeetingStart.TotalMinutes <= m.MeetingWarningMinutes.TotalMinutes) // Meeting is about to start changeType = eMeetingEventChangeType.MeetingStartWarning; @@ -98,12 +113,17 @@ namespace PepperDash.Essentials.Core.Devices.Codec /// public class Meeting { - public TimeSpan MeetingWarningMinutes = TimeSpan.FromMinutes(5); + public int MinutesBeforeMeeting; public string Id { get; set; } public string Organizer { get; set; } public string Title { get; set; } public string Agenda { get; set; } + + public TimeSpan MeetingWarningMinutes + { + get { return TimeSpan.FromMinutes(MinutesBeforeMeeting); } + } public TimeSpan TimeToMeetingStart { get @@ -132,7 +152,7 @@ namespace PepperDash.Essentials.Core.Devices.Codec { get { - return StartTime.AddMinutes(-5) <= DateTime.Now + return StartTime.AddMinutes(-MinutesBeforeMeeting) <= DateTime.Now && DateTime.Now <= EndTime; //.AddMinutes(-5); } } diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Interfaces/IHasCameraPresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Interfaces/IHasCameraPresets.cs new file mode 100644 index 00000000..a8e8983d --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/Interfaces/IHasCameraPresets.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Devices.Common.Cameras +{ + /// + /// Describes a camera with preset functionality + /// + public interface IHasCameraPresets + { + event EventHandler PresetsListHasChanged; + + List Presets { get; } + + void PresetSelect(int preset); + + void PresetStore(int preset, string description); + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/RoomPresets.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/RoomPresets.cs new file mode 100644 index 00000000..5ae3b86a --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Devices/RoomPresets.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using Newtonsoft.Json; + +using PepperDash.Core; +using PepperDash.Essentials.Core.Presets; + +namespace PepperDash.Essentials.Devices.Common.VideoCodec +{ + /// + /// Interface for camera presets + /// + public interface IHasCodecRoomPresets + { + event EventHandler CodecRoomPresetsListHasChanged; + + List NearEndPresets { get; } + + List FarEndRoomPresets { get; } + + void CodecRoomPresetSelect(int preset); + + void CodecRoomPresetStore(int preset, string description); + } + + /// + /// Represents a room preset on a video codec. Typically stores camera position(s) and video routing. Can be recalled by Far End if enabled. + /// + public class CodecRoomPreset : PresetBase + { + public CodecRoomPreset(int id, string description, bool def, bool isDef) + : base(id, description, def, isDef) + { + + } + } +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index 283df563..c7dc47fb 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -199,11 +199,13 @@ + + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/Config/EssentialsVolumeLevelConfig.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/Config/EssentialsVolumeLevelConfig.cs index fa2ebc5b..7379e51a 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/Config/EssentialsVolumeLevelConfig.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/Config/EssentialsVolumeLevelConfig.cs @@ -1,4 +1,4 @@ -namespace PepperDash.Essentials +namespace PepperDash.Essentials.Core { /// /// diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/EssentialsRoomBase.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/EssentialsRoomBase.cs index 2d2ce439..80b977a9 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/EssentialsRoomBase.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Rooms/EssentialsRoomBase.cs @@ -5,6 +5,7 @@ using Crestron.SimplSharp; using PepperDash.Core; using PepperDash.Essentials.Core.Config; using PepperDash.Essentials.Core.Devices; +using PepperDash.Essentials.Core.DeviceTypeInterfaces; using PepperDash.Essentials.Core.Rooms.Config; namespace PepperDash.Essentials.Core @@ -20,6 +21,21 @@ namespace PepperDash.Essentials.Core protected Func IsWarmingFeedbackFunc; protected string LastSourceKey; + + public string LogoUrlLightBkgnd { get; set; } + + public string LogoUrlDarkBkgnd { get; set; } + + /// + /// Indicates if this room is Mobile Control Enabled + /// + public bool IsMobileControlEnabled { get; private set; } + + /// + /// The bridge for this room if Mobile Control is enabled + /// + public IMobileControlRoomBridge MobileControlRoomBridge { get; private set; } + /// /// /// @@ -222,6 +238,27 @@ namespace PepperDash.Essentials.Core VacancyMode = eVacancyMode.None; } + /// + /// If mobile control is enabled, sets the appropriate properties + /// + void SetUpMobileControl() + { + var mcBridgeKey = string.Format("mobileControlBridge-{0}", Key); + var mcBridge = DeviceManager.GetDeviceForKey(mcBridgeKey); + if (mcBridge == null) + { + Debug.Console(1, this, "*********************Mobile Control Bridge Not found for this room."); + IsMobileControlEnabled = false; + return; + } + else + { + MobileControlRoomBridge = mcBridge as IMobileControlRoomBridge; + Debug.Console(1, this, "*********************Mobile Control Bridge found and enabled for this room"); + IsMobileControlEnabled = true; + } + } + private void SetupShutdownPrompt() { // Setup the ShutdownPromptTimer diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs index 70596904..250b29d5 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Audio/GenericAudioOut.cs @@ -15,7 +15,7 @@ namespace PepperDash.Essentials.Devices.Common /// /// Represents and audio endpoint /// - public class GenericAudioOut : EssentialsDevice, IRoutingSinkNoSwitching + public class GenericAudioOut : EssentialsDevice, IRoutingSink { public event SourceInfoChangeHandler CurrentSourceChange; diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj index a49ec402..c1329883 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/Essentials Devices Common.csproj @@ -98,7 +98,6 @@ - @@ -107,7 +106,6 @@ - diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs index 90ab1081..5f5a4e5b 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/SoftCodec/BlueJeansPc.cs @@ -94,9 +94,9 @@ namespace PepperDash.Essentials.Devices.Common.SoftCodec /// bool DoRoute(SourceRouteListItem route) { - IRoutingSinkNoSwitching dest = null; + IRoutingSink dest = null; - dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching; + dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSink; if (dest == null) { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs index b8e285c7..a511cf2d 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/CiscoSparkCodec.cs @@ -289,6 +289,36 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco public RoutingOutputPort HdmiOut1 { get; private set; } public RoutingOutputPort HdmiOut2 { get; private set; } + public static List GetGenericPresets(List presets) + { + var cameraPresets = new List(); + + if (Debug.Level > 0) + { + Debug.Console(1, "Presets List:"); + } + + foreach (CiscoCodecStatus.RoomPreset preset in presets) + { + try + { + var cameraPreset = new CodecRoomPreset(UInt16.Parse(preset.id), preset.Description.Value, preset.Defined.BoolValue, true); + + cameraPresets.Add(cameraPreset); + + if (Debug.Level > 0) + { + Debug.Console(1, "Added Preset ID: {0}, Description: {1}, IsDefined: {2}, isDefinable: {3}", cameraPreset.ID, cameraPreset.Description, cameraPreset.Defined, cameraPreset.IsDefinable); + } + } + catch (Exception e) + { + Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", preset.id, e); + } + } + + return cameraPresets; + } // Constructor for IBasicCommunication public CiscoSparkCodec(DeviceConfig config, IBasicCommunication comm) @@ -457,6 +487,57 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco TieLineCollection.Default.Add(tl); } + public void ConvertCiscoCallHistoryToGeneric(List entries) + { + var genericEntries = new List(); + + foreach (CiscoCallHistory.Entry entry in entries) + { + + genericEntries.Add(new CodecCallHistory.CallHistoryEntry() + { + Name = entry.DisplayName.Value, + Number = entry.CallbackNumber.Value, + StartTime = entry.LastOccurrenceStartTime.Value, + OccurrenceHistoryId = entry.LastOccurrenceHistoryId.Value, + OccurrenceType = ConvertToOccurenceTypeEnum(entry.OccurrenceType.Value) + }); + } + + // Check if list is empty and if so, add an item to display No Recent Calls + if (genericEntries.Count == 0) + genericEntries.Add(CallHistory.ListEmptyEntry); + + CallHistory.UpdateCallHistory(genericEntries); + } + + /// + /// Takes the Cisco occurence type and converts it to the matching enum + /// + /// -1 || response.IndexOf("\"CallHistoryDeleteEntryResult\": {") > -1) { diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs index 88a0f2c9..5b208fa9 100644 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs +++ b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/PhonebookDataClasses.cs @@ -241,7 +241,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec foreach (ContactMethod m in c.ContactMethod) { - var tempContactMethod = new Essentials.Core.Devices.Codec.ContactMethod(); + var tempContactMethod = new Codec.ContactMethod(); eContactMethodCallType callType = eContactMethodCallType.Unknown; if (!string.IsNullOrEmpty(m.CallType.Value)) @@ -300,11 +300,11 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec /// public static CodecDirectory ConvertCiscoPhonebookToGeneric(PhonebookSearchResult result) { - var directory = new Essentials.Core.Devices.Codec.CodecDirectory(); + var directory = new CodecDirectory(); - var folders = new List(); + var folders = new List(); - var contacts = new List(); + var contacts = new List(); try { @@ -371,7 +371,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec device = eContactMethodDevice.Other; } - contact.ContactMethods.Add(new Essentials.Core.Devices.Codec.ContactMethod() + contact.ContactMethods.Add(new Codec.ContactMethod() { Number = m.Number.Value, ContactMethodId = m.ContactMethodId.Value, diff --git a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs b/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs deleted file mode 100644 index 1b456774..00000000 --- a/essentials-framework/Essentials Devices Common/Essentials Devices Common/VideoCodec/CiscoCodec/RoomPresets.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using Newtonsoft.Json; - -using PepperDash.Core; -using PepperDash.Essentials.Core.Presets; -using PepperDash.Essentials.Devices.Common.VideoCodec.Cisco; - -namespace PepperDash.Essentials.Devices.Common.VideoCodec -{ - /// - /// Interface for camera presets - /// - public interface IHasCodecRoomPresets - { - event EventHandler CodecRoomPresetsListHasChanged; - - List NearEndPresets { get; } - - List FarEndRoomPresets { get; } - - void CodecRoomPresetSelect(int preset); - - void CodecRoomPresetStore(int preset, string description); - } - - public static class RoomPresets - { - /// - /// Converts Cisco RoomPresets to generic CameraPresets - /// - /// - /// - public static List GetGenericPresets(List presets) - { - var cameraPresets = new List(); - - if (Debug.Level > 0) - { - Debug.Console(1, "Presets List:"); - } - - foreach (CiscoCodecStatus.RoomPreset preset in presets) - { - try - { - var cameraPreset = new CodecRoomPreset(UInt16.Parse(preset.id), preset.Description.Value, preset.Defined.BoolValue, true); - - cameraPresets.Add(cameraPreset); - - if (Debug.Level > 0) - { - Debug.Console(1, "Added Preset ID: {0}, Description: {1}, IsDefined: {2}, isDefinable: {3}", cameraPreset.ID, cameraPreset.Description, cameraPreset.Defined, cameraPreset.IsDefinable); - } - } - catch (Exception e) - { - Debug.Console(2, "Unable to convert preset: {0}. Error: {1}", preset.id, e); - } - } - - return cameraPresets; - } - } - - /// - /// Represents a room preset on a video codec. Typically stores camera position(s) and video routing. Can be recalled by Far End if enabled. - /// - public class CodecRoomPreset : PresetBase - { - public CodecRoomPreset(int id, string description, bool def, bool isDef) - : base(id, description, def, isDef) - { - - } - } -} \ No newline at end of file