diff --git a/PepperDashEssentials/Bridges/BridgeFactory.cs b/PepperDashEssentials/Bridges/BridgeFactory.cs index 8b9ba75c..923ee59f 100644 --- a/PepperDashEssentials/Bridges/BridgeFactory.cs +++ b/PepperDashEssentials/Bridges/BridgeFactory.cs @@ -128,13 +128,13 @@ public class BridgeApiEisc { if (Debug.Level >= 1) Debug.Console(1, "BridgeApiEisc change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue); - var uo = args.Sig.UserObject; - if (uo is Action) - (uo as Action)(args.Sig.BoolValue); - else if (uo is Action) - (uo as Action)(args.Sig.UShortValue); - else if (uo is Action) - (uo as Action)(args.Sig.StringValue); + var uo = args.Sig.UserObject; + if (uo is Action) + CrestronInvoke.BeginInvoke(o => (uo as Action)((o as SigEventArgs).Sig.BoolValue), args); + else if (uo is Action) + CrestronInvoke.BeginInvoke(o => (uo as Action)((o as SigEventArgs).Sig.UShortValue), args); + else if (uo is Action) + CrestronInvoke.BeginInvoke(o => (uo as Action)((o as SigEventArgs).Sig.StringValue), args); } } } diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 8124beb7..44ebc31f 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -19,35 +19,35 @@ using PepperDash.Essentials.Room.Cotija; namespace PepperDash.Essentials { - public class ControlSystem : CrestronControlSystem - { + public class ControlSystem : CrestronControlSystem + { HttpLogoServer LogoServer; - List FactoryObjects = new List(); + List FactoryObjects = new List(); - public ControlSystem() - : base() - { - Thread.MaxNumberOfUserThreads = 400; - Global.ControlSystem = this; - DeviceManager.Initialize(this); - } + public ControlSystem() + : base() + { + Thread.MaxNumberOfUserThreads = 400; + Global.ControlSystem = this; + DeviceManager.Initialize(this); + } - /// - /// Git 'er goin' - /// - public override void InitializeSystem() - { + /// + /// Git 'er goin' + /// + public override void InitializeSystem() + { DeterminePlatform(); //CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file", // ConsoleAccessLevelEnum.AccessOperator); - // CrestronConsole.AddNewConsoleCommand(S => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", 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 => { ConfigWriter.WriteConfigFile(null); }, "writeconfig", "writes the current config to a file", 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 => { @@ -56,23 +56,23 @@ namespace PepperDash.Essentials }, "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 + ("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(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); GoWithLoad(); - } + } /// /// Determines if the program is running on a processor (appliance) or server (VC-4). @@ -100,11 +100,11 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString); // Check if User/ProgramX exists - if(Directory.Exists(directoryPrefix + dirSeparator + "User" + if (Directory.Exists(directoryPrefix + dirSeparator + "User" + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber))) { Debug.Console(0, @"User/program{0} directory found", InitialParametersClass.ApplicationNumber); - filePathPrefix = directoryPrefix + dirSeparator + "User" + filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; } // Check if Nvram/Programx exists @@ -134,165 +134,198 @@ namespace PepperDash.Essentials Global.SetFilePathPrefix(filePathPrefix); } - /// - /// Do it, yo - /// - public void GoWithLoad() - { - try - { + /// + /// Do it, yo + /// + public void GoWithLoad() + { + try + { 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"); - LoadPlugins(); + var filesReady = SetupFilesystem(); + if (filesReady) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Checking for plugins"); + LoadPlugins(); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config..."); - if (!ConfigReader.LoadConfig2()) - return; + if (!ConfigReader.LoadConfig2()) + return; - Load(); + Load(); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r" + - "-------------------------------------------------------------"); - } - else - { - Debug.Console(0, - "------------------------------------------------\r" + - "------------------------------------------------\r" + - "------------------------------------------------\r" + - "Essentials file structure setup completed.\r" + - "Please load config, sgd and ir files and\r" + - "restart program.\r" + - "------------------------------------------------\r" + - "------------------------------------------------\r" + - "------------------------------------------------"); - } + "-------------------------------------------------------------"); + } + else + { + Debug.Console(0, + "------------------------------------------------\r" + + "------------------------------------------------\r" + + "------------------------------------------------\r" + + "Essentials file structure setup completed.\r" + + "Please load config, sgd and ir files and\r" + + "restart program.\r" + + "------------------------------------------------\r" + + "------------------------------------------------\r" + + "------------------------------------------------"); + } } - catch (Exception e) - { - Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e); + catch (Exception e) + { + Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e); - } + } // Notify the OS that the program intitialization has completed SystemMonitor.ProgramInitialization.ProgramInitializationComplete = true; - } + } - /// - /// Initial simple implementation. Reads user/programN/plugins folder and - /// use - /// - void LoadPlugins() - { - var dir = Global.FilePathPrefix + "plugins"; - if (Directory.Exists(dir)) - { - // TODO Clear out or create localPlugins folder (maybe in program slot folder) + /// + /// Initial simple implementation. Reads user/programN/plugins folder and + /// use + /// + void LoadPlugins() + { + var dir = Global.FilePathPrefix + "plugins"; + if (Directory.Exists(dir)) + { + // TODO Clear out or create localPlugins folder (maybe in program slot folder) - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for factory plugins"); - var di = new DirectoryInfo(dir); - var files = di.GetFiles("*.dll"); - foreach (FileInfo fi in files) - { - // TODO COPY plugin to loadedPlugins folder + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Plugins directory found, checking for factory plugins"); + var di = new DirectoryInfo(dir); + var zFiles = di.GetFiles("*.cplz"); + foreach (var fi in zFiles) + { + Debug.Console(0, "Found cplz: {0}. Unzipping into plugins directory", fi.Name); + var result = CrestronZIP.Unzip(fi.FullName, di.FullName); + Debug.Console(0, "UnZip Result: {0}", result.ToString()); + fi.Delete(); + } + var files = di.GetFiles("*.dll"); + Dictionary assyList = new Dictionary(); + foreach (FileInfo fi in files) + { + // TODO COPY plugin to loadedPlugins folder + // TODO LOAD that loadedPlugins dll file + try + { + var assy = Assembly.LoadFrom(fi.FullName); + var ver = assy.GetName().Version; + var verStr = string.Format("{0}.{1}.{2}.{3}", ver.Major, ver.Minor, ver.Build, ver.Revision); + assyList.Add(fi.FullName, assy); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded plugin file '{0}', version {1}", fi.FullName, verStr); + } + catch + { + Debug.Console(2, "Assembly {0} is not a custom assembly", fi.FullName); + continue; //catching any load issues and continuing. There will be exceptions loading Crestron .dlls from the cplz Probably should do something different here + } + } + foreach (var assy in assyList) + { + // iteratate this assembly's classes, looking for "LoadPlugin()" methods + try + { + var types = assy.Value.GetTypes(); + foreach (var type in types) + { + try + { + var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); + var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); + if (loadPlugin != null) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding type {0}", assy.Key, type.FullName); + loadPlugin.Invoke(null, null); + } + } + catch + { + Debug.Console(2, "Load Plugin not found. {0} is not a plugin assembly", assy.Value.FullName); + continue; + } - // TODO LOAD that loadedPlugins dll file + } + } + catch + { + Debug.Console(2, "Assembly {0} is not a custom assembly. Types cannot be loaded.", assy.Value.FullName); + continue; + } + } + // plugin dll will be loaded. Any classes in plugin should have a static constructor + // that registers that class with the Core.DeviceFactory + } + } - var assy = Assembly.LoadFrom(fi.FullName); - var ver = assy.GetName().Version; - var verStr = string.Format("{0}.{1}.{2}.{3}", ver.Major, ver.Minor, ver.Build, ver.Revision); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loaded plugin file '{0}', version {1}", fi.FullName, verStr); + /// + /// 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); - // iteratate this assembly's classes, looking for "LoadPlugin()" methods - var types = assy.GetTypes(); - foreach (var type in types) - { - var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static); - var loadPlugin = methods.FirstOrDefault(m => m.Name.Equals("LoadPlugin")); - if (loadPlugin != null) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding type {0}", fi.FullName, type.FullName); - loadPlugin.Invoke(null, null); - } - - } - - // plugin dll will be loaded. Any classes in plugin should have a static constructor - // that registers that class with the Core.DeviceFactory - } - } - } - - /// - /// 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 irDir = Global.FilePathPrefix + "ir"; + if (!Directory.Exists(irDir)) + Directory.Create(irDir); var sgdDir = Global.FilePathPrefix + "sgd"; - if (!Directory.Exists(sgdDir)) - Directory.Create(sgdDir); + if (!Directory.Exists(sgdDir)) + Directory.Create(sgdDir); - return configExists; - } + return configExists; + } - ///// - ///// - ///// - ///// - //public void EnablePortalSync(string s) - //{ - // if (s.ToLower() == "enable") - // { - // CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled"); - // } - //} + ///// + ///// + ///// + ///// + //public void EnablePortalSync(string s) + //{ + // if (s.ToLower() == "enable") + // { + // CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled"); + // } + //} - /// - /// - /// - public void TearDown() - { - Debug.Console(0, "Tearing down existing system"); - DeviceManager.DeactivateAll(); + /// + /// + /// + public void TearDown() + { + Debug.Console(0, "Tearing down existing system"); + DeviceManager.DeactivateAll(); - TieLineCollection.Default.Clear(); + TieLineCollection.Default.Clear(); - foreach (var key in DeviceManager.GetDevices()) - DeviceManager.RemoveDevice(key); + foreach (var key in DeviceManager.GetDevices()) + DeviceManager.RemoveDevice(key); - Debug.Console(0, "Tear down COMPLETE"); - } + Debug.Console(0, "Tear down COMPLETE"); + } - /// - /// - /// - void Load() - { - LoadDevices(); - LoadTieLines(); - LoadRooms(); - LoadLogoServer(); + /// + /// + /// + void Load() + { + LoadDevices(); + LoadTieLines(); + LoadRooms(); + LoadLogoServer(); - DeviceManager.ActivateAll(); + DeviceManager.ActivateAll(); LinkSystemMonitorToAppServer(); - } + } void LinkSystemMonitorToAppServer() { @@ -309,28 +342,28 @@ namespace PepperDash.Essentials messenger.RegisterWithAppServer(appServer); - DeviceManager.AddDevice(messenger); + DeviceManager.AddDevice(messenger); } } - /// - /// 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")); + /// + /// 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 DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor")); - foreach (var devConf in ConfigReader.ConfigObject.Devices) - { + foreach (var devConf in ConfigReader.ConfigObject.Devices) + { - try - { + try + { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}', type '{1}'", devConf.Key, devConf.Type); - // Skip this to prevent unnecessary warnings + // Skip this to prevent unnecessary warnings if (devConf.Key == "processor") { if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower()) @@ -341,94 +374,94 @@ namespace PepperDash.Essentials continue; } - // Try local factories first - var newDev = DeviceFactory.GetDevice(devConf); + // Try local factories first + var newDev = DeviceFactory.GetDevice(devConf); if (newDev == null) newDev = BridgeFactory.GetDevice(devConf); - // Then associated library factories + // Then associated library factories if (newDev == null) newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.BridgeFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.BridgeFactory.GetDevice(devConf); - //if (newDev == null) // might want to consider the ability to override an essentials "type" - //{ - // // iterate plugin factories - // foreach (var f in FactoryObjects) - // { - // var cresFactory = f as IGetCrestronDevice; - // if (cresFactory != null) - // { - // newDev = cresFactory.GetDevice(devConf, this); - // } - // } - //} + //if (newDev == null) // might want to consider the ability to override an essentials "type" + //{ + // // iterate plugin factories + // foreach (var f in FactoryObjects) + // { + // var cresFactory = f as IGetCrestronDevice; + // if (cresFactory != null) + // { + // newDev = cresFactory.GetDevice(devConf, this); + // } + // } + //} - if (newDev != null) - DeviceManager.AddDevice(newDev); - else + 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) - { + } + 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 + /// + /// 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; - } + 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); - } + 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.Warning, "WARNING: Configuration contains no rooms"); - return; - } + /// + /// Reads all rooms from config and adds them to DeviceManager + /// + public void LoadRooms() + { + if (ConfigReader.ConfigObject.Rooms == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "WARNING: Configuration contains no rooms"); + return; + } - foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) - { + foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) + { var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase; - if (room != null) - { + if (room != null) + { if (room is EssentialsHuddleSpaceRoom) { DeviceManager.AddDevice(room); @@ -438,10 +471,10 @@ namespace PepperDash.Essentials Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge..."); - // Cotija bridge - var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom); - AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present - DeviceManager.AddDevice(bridge); + // Cotija bridge + var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom); + AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present + DeviceManager.AddDevice(bridge); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Cotija Bridge Added..."); } @@ -452,60 +485,60 @@ namespace PepperDash.Essentials 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 Cotija Bridge..."); - // Cotija bridge - var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room); - AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present - DeviceManager.AddDevice(bridge); - } + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge..."); + // Cotija bridge + var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room); + AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present + DeviceManager.AddDevice(bridge); + } else { Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsRoom, attempting to add to DeviceManager w/o Fusion"); DeviceManager.AddDevice(room); } - } - else + } + else Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key); - } + } Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded."); - } + } - /// - /// Helps add the post activation steps that link bridges to main controller - /// - /// - void AddBridgePostActivationHelper(CotijaBridgeBase bridge) - { - bridge.AddPostActivationAction(() => - { - var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController; - if (parent == null) - { - Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present"); - return; - } - Debug.Console(0, bridge, "Linking to parent controller"); - bridge.AddParent(parent); - parent.AddBridge(bridge); - }); - } + /// + /// Helps add the post activation steps that link bridges to main controller + /// + /// + void AddBridgePostActivationHelper(CotijaBridgeBase bridge) + { + bridge.AddPostActivationAction(() => + { + var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController; + if (parent == null) + { + Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present"); + return; + } + Debug.Console(0, bridge, "Linking to parent controller"); + bridge.AddParent(parent); + parent.AddBridge(bridge); + }); + } - /// - /// Fires up a logo server if not already running - /// - void LoadLogoServer() - { - try - { + /// + /// Fires up a logo server if not already running + /// + void LoadLogoServer() + { + 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"); - } - } - } + catch (Exception) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program"); + } + } + } }