diff --git a/.gitignore b/.gitignore
index 0d54c09f4a8eec136e8fae2a71833814ee04105f..eeb09a4fd68f3c01161a6f6d27b204329a29f3d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -111,5 +111,6 @@ _b_asic_debug_log.txt
 .qt_for_python/
 *.pyproject.user
 *.pyproject
-*/scheduler-gui/ui/
-TODO.txt
\ No newline at end of file
+ui_*.py
+TODO.txt
+*.log
\ No newline at end of file
diff --git a/b_asic/scheduler-gui/__init__.py b/b_asic/scheduler-gui/__init__.py
index 4633afec3b124ddb439571cb05a302f6c85ab29f..c18cf2c1978e59a4d2f0d1d7e978e4bd39cd501d 100644
--- a/b_asic/scheduler-gui/__init__.py
+++ b/b_asic/scheduler-gui/__init__.py
@@ -2,5 +2,10 @@
 
 Graphical user interface for B-ASIC scheduler.
 """
-from b_asic.schedule-gui.main_window import *
-from b_asic.schedule-gui.schedule import *
\ No newline at end of file
+
+from .main_window import *
+from .scheduler import *
+
+#__all__ = ['main_window', 'scheduler']
+__version__ = '0.1'
+__author__ = 'Andreas Bolin'
diff --git a/b_asic/scheduler-gui/logger.py b/b_asic/scheduler-gui/logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..3dfbbebbc092b519b2901bb0cad033aba06b3e44
--- /dev/null
+++ b/b_asic/scheduler-gui/logger.py
@@ -0,0 +1,80 @@
+# This Python file uses the following encoding: utf-8
+""" B-ASIC Scheduler-gui Logger Module.
+
+Contains a logger that logs to the console and a file using levels. It is based
+on the `logging` module and has predefined levels of logging.
+
+Usage:
+------
+
+    >>> import logger  
+    >>> log = logger.getLogger()  
+    >>> log.info('This is a log post with level INFO')  
+
+| Function call  | Level     | Numeric value |
+|----------------|-----------|---------------|
+| debug(str)     | DEBUG     | 10            |
+| info(str)      | INFO      | 20            |
+| warning(str)   | WARNING   | 30            |
+| error(str)     | ERROR     | 40            |
+| critical(str)  | CRITICAL  | 50            |
+| exception(str) | ERROR     | 40            |
+
+The last `exception(str)` is used to capture exceptions output, that normally
+won't be captured.  
+See https://docs.python.org/3/howto/logging.html for more information.
+"""
+from logging import Logger
+import logging
+import logging.handlers
+import os
+import sys
+
+
+def getLogger(name: str='scheduler-gui.log', loglevel: str='DEBUG') -> Logger:
+    """This function creates console- and filehandler and from those, creates a logger object.
+
+    Args:
+        name (str, optional): Logger-id and output filename. Defaults to 'scheduler-gui.log'.
+        loglevel (str, optional): The minimum level that the logger will log. Defaults to 'DEBUG'.
+
+    Returns:
+        Logger: 'logging.Logger' object.
+    """
+
+    logger = logging.getLogger(name)
+
+    # if logger 'name' already exists, return it to avoid logging duplicate
+    # messages by attaching multiple handlers of the same type
+    if logger.handlers:
+        return logger
+    # if logger 'name' does not already exist, create it and attach handlers
+    else:
+        # set logLevel to loglevel or to INFO if requested level is incorrect
+        loglevel = getattr(logging, loglevel.upper(), logging.DEBUG)
+        logger.setLevel(loglevel)
+        
+        # setup the console logger
+        c_fmt_date = '%T'
+        c_fmt = '[%(process)d] %(asctime)s %(filename)18s:%(lineno)-4s %(funcName)18s() %(levelname)-8s: %(message)s'
+        c_formatter = logging.Formatter(c_fmt, c_fmt_date)
+        c_handler = logging.StreamHandler()
+        c_handler.setFormatter(c_formatter)
+        c_handler.setLevel(logging.WARNING)
+        logger.addHandler(c_handler)
+        
+        # setup the file logger
+        f_fmt_date = '%Y-%m-%dT%T%Z'
+        f_fmt = '%(asctime)s %(filename)18s:%(lineno)-4s %(funcName)18s() %(levelname)-8s: %(message)s'
+        f_formatter = logging.Formatter(f_fmt, f_fmt_date)
+        f_handler = logging.FileHandler(name, mode = 'w')
+        f_handler.setFormatter(f_formatter)
+        f_handler.setLevel(logging.DEBUG)
+        logger.addHandler(f_handler)
+
+    if logger.name == 'scheduler-gui.log':
+        logger.info('Running: %s %s',
+                    os.path.basename(sys.argv[0]),
+                    ' '.join(sys.argv[1:]))
+        
+    return logger
diff --git a/b_asic/scheduler-gui/main_window.py b/b_asic/scheduler-gui/main_window.py
index 33e82c58d91da0b49220ba0cf5dd53855d2d5e10..2b53cb3d1761934491df842dd6ea8640b4813ae3 100644
--- a/b_asic/scheduler-gui/main_window.py
+++ b/b_asic/scheduler-gui/main_window.py
@@ -13,6 +13,7 @@ from pathlib        import Path
 from typing         import Any
 #from matplotlib.pyplot import bar
 #from diagram import *
+import logger
 
 import qtpy
 from qtpy           import uic, QtCore, QtGui, QtWidgets
@@ -33,6 +34,8 @@ from qtpy.QtCore    import (
     QRect)
 
 
+log = logger.getLogger()
+
 # Debug struff
 if __debug__:
     # Print some system version information
@@ -50,16 +53,19 @@ if __debug__:
     # Autocompile the .ui form to a python file.
     try:                                        # PyQt5, try autocompile
         from qtpy.uic import compileUiDir
-        def _map_func(dir: str, file: str) -> tuple[str, str]:
-            file_base,_ = os.path.splitext(file)
-            return (dir+'/ui/', file_base+'_ui.py')
-        uic.compileUiDir('.', False, _map_func)
+        # def _map_func(dir: str, file: str) -> tuple[str, str]:
+        #     file_base,_ = os.path.splitext(file)
+        #     return (dir+'/ui/', file_base+'_ui.py')
+        # uic.compileUiDir('.', map=_map_func)
+        
+        uic.compileUiDir('.', map=(lambda dir,file: dir, 'ui_' + file))
     except:
         try:                                    # PySide2, try manual compile
             import subprocess
-            OS = sys.platform
-            if OS.startswith('linux'):
-                cmds = ["mkdir -p ui", "pyside2-uic -o ui/main_window_ui.py main_window.ui"]
+            os_ = sys.platform
+            if os_.startswith('linux'):
+                cmds = ["mkdir -p ui",
+                        "pyside2-uic -o ui_main_window.py main_window.ui"]
                 for cmd in cmds:
                     subprocess.call(cmd.split())
             else:
@@ -67,14 +73,14 @@ if __debug__:
                 raise SystemExit
         except:                                 # Compile failed, look for pre-compiled file
             try:
-                from ui.main_window_ui import Ui_MainWindow
+                from ui_main_window import Ui_MainWindow
             except:                             # Everything failed, exit
-                print("ERROR: Could not import 'Ui_MainWindow'.")
-                print("ERROR: Can't autocompile under", QT_API, "eviroment. Try to manual compile 'main_window.ui' to 'ui/main_window_ui.py'")
+                log.exception("Could not import 'Ui_MainWindow'.")
+                log.exception("Can't autocompile under", QT_API, "eviroment. Try to manual compile 'main_window.ui' to 'ui/main_window_ui.py'")
                 os._exit(1)
 
-# Only availible when the form is compiled
-from ui.main_window_ui import Ui_MainWindow
+
+from ui_main_window import Ui_MainWindow             # Only availible when the form is compiled
 
 
 
@@ -84,17 +90,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
 
     _settings: QSettings
     
-
     def __init__(self):
         """Initialize Schedule-gui."""
         super(MainWindow, self).__init__()
         self._init_ui()
         self._init_graphics_view()
-
+       
+        
 
     def _init_ui(self) -> None:
         """Initialize the ui"""
-
         self._settings = QSettings()
         self.setupUi(self)
 
@@ -103,7 +108,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.menu_load_sfg.triggered.connect(self.open)
         self.menu_save_schedule.triggered.connect(self.save)
         self.menu_quit.triggered.connect(self.close)
-        self.menu_node_info.triggered.connect(self._toggle_component_info)
+        self.menu_node_info.triggered.connect(self.toggle_component_info)
         self.splitter_center.splitterMoved.connect(self._splitter_center_moved)
 
         # Setup event member functions
@@ -121,7 +126,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.splitter_center.setCollapsible(1, True)
 
     def _init_graphics_view(self) -> None:
-        """Initialize the QGraphics"""
+        """Initialize the QGraphics framework"""
         self.graphic_scene = QGraphicsScene(self)
         self.graphic_view.setScene(self.graphic_scene)
         self.graphic_view.setRenderHint(QPainter.Antialiasing)
@@ -153,7 +158,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
         self.update_statusbar(self.tr('Schedule saved successfully'))
     
     @Slot(bool)
-    def _toggle_component_info(self, checked: bool) -> None:
+    def toggle_component_info(self, checked: bool) -> None:
         """This method toggles the right hand side info window."""
         widths = list(self.splitter_center.sizes())
         max_range = widths[0] + widths[1]
diff --git a/b_asic/scheduler-gui/schedule-demo.py b/b_asic/scheduler-gui/tests/schedule-demo.py
similarity index 100%
rename from b_asic/scheduler-gui/schedule-demo.py
rename to b_asic/scheduler-gui/tests/schedule-demo.py