void LoadUserInterfaceSmartObjectGraphics(BasicTriListWithSmartObject currentDevice)
 {
     try
     {
         string location = Directory.GetApplicationDirectory() + "\\" + SgdFileName;
         if (File.Exists(location))
         {
             currentDevice.LoadSmartObjects(location);
             OnDebug(eDebugEventType.Info, "{0} SmartObject items loaded", currentDevice.SmartObjects.Count.ToString());
             foreach (KeyValuePair <uint, SmartObject> kvp in currentDevice.SmartObjects)
             {
                 kvp.Value.SigChange += new SmartObjectSigChangeEventHandler(SmartObject_SigChange);
                 SG.PrintSmartObjectSigNames(kvp.Value);
             }
         }
         else
         {
             OnDebug(eDebugEventType.Info, "SmartObject file{0} does not exist", location);
         }
     }
     catch (Exception e)
     {
         OnDebug(eDebugEventType.Error, "Exception in LoadUserInterfaceSmartObjectGraphics: {0}", e.Message);
     }
 }
        bool isAccessLevelChosen = false;                               // Indicates whether user has clicked an access level (cannot create group if false)
        /////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// ControlSystem Constructor. Starting point for the SIMPL#Pro program.
        /// Use the constructor to:
        /// * Initialize the maximum number of threads (max = 400)
        /// * Register devices
        /// * Register event handlers
        /// * Add Console Commands
        ///
        /// Please be aware that the constructor needs to exit quickly; if it doesn't
        /// exit in time, the SIMPL#Pro program will exit.
        ///
        /// You cannot send / receive data in the constructor
        /// </summary>
        public ControlSystem()
            : base()
        {
            try
            {
                //Subscribe to the controller events (System, Program, and Ethernet)
                CrestronEnvironment.SystemEventHandler        += new SystemEventHandler(ControlSystem_ControllerSystemEventHandler);
                CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(ControlSystem_ControllerProgramEventHandler);

                // IPID = 3
                panel = new Tsw752(0x3, this);

                // Subscribe to all signal changes from the touchpanel. This handler will be invoked everytime the
                // user presses a button or types into a text box
                panel.SigChange += new SigEventHandler(Panel_SigChange);
                // If the smart graphics file exists, load it to the panel
                if (File.Exists(Directory.GetApplicationDirectory() + "\\" + sgdFileName))
                {
                    panel.LoadSmartObjects(Directory.GetApplicationDirectory() + "\\" + sgdFileName);

                    // Register the event handler for each Smart Object found
                    foreach (KeyValuePair <uint, SmartObject> so in panel.SmartObjects)
                    {
                        so.Value.SigChange += new SmartObjectSigChangeEventHandler(SmartObject_SigChange);
                    }
                }
                else
                {
                    ErrorLog.Error("Failed to load SGD file {0} for panel", sgdFileName);
                }

                if (panel.Register() != eDeviceRegistrationUnRegistrationResponse.Success)
                {
                    ErrorLog.Error("Error Registering panel at IPID {0}: {1}", panel.ID, panel.RegistrationFailureReason);
                }

                // Create the timer now, but don't start it until the user logs in
                authTimeout = new CTimer(authTimeoutCallback, Timeout.Infinite);
            }
            catch (Exception e)
            {
                CrestronConsole.PrintLine("Error in the constructor: {0}", e);
                ErrorLog.Error("Error in the constructor: {0}", e.Message);
            }
        }