Esempio n. 1
0
def launch(**kwargs):
    """ Connects to NI-daqMX card and launches server
    Identical to nidaqmx, except uses "device_ai" in the config file as the device name

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    # Instantiate driver
    logger = kwargs['logger']
    config = kwargs['config']
    config = load_device_config('fw102c', config, logger=kwargs['logger'])

    device_name = config['device_name']
    port_name = config['device_id']
    filters = config['filters']
    filters = {f'{i+1}': f'{filters[i]} OD' for i in range(len(filters))}
    filterwheel = FW102CFilterWheel(port_name=port_name,
                                    device_name=device_name,
                                    filters=filters,
                                    logger=logger)

    filterwheel_service = Service()
    filterwheel_service.assign_module(module=filterwheel)
    filterwheel_service.assign_logger(logger=logger)
    filterwheel_service_server = GenericServer(service=filterwheel_service,
                                               host=get_ip(),
                                               port=kwargs['port'])

    filterwheel_service_server.start()
Esempio n. 2
0
def launch(**kwargs):
    """ Connects to NI-daqMX card and launches server
    Identical to nidaqmx, except uses "device_ai" in the config file as the device name

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    # Instantiate driver
    logger = kwargs['logger']
    config = kwargs['config']
    config = load_device_config('agc_100', config, logger=kwargs['logger'])

    port_name = config['device_id']
    agc = AGC_100(port=port_name, logger=logger)

    agc_service = Service()
    agc_service.assign_module(module=agc)
    agc_service.assign_logger(logger=logger)
    agc__server = GenericServer(
        service=agc_service,
        host=get_ip(),
        port=kwargs['port']
    )

    agc__server.start()
Esempio n. 3
0
def launch(**kwargs):
    """ Connects to Tektronix TDS2004C oscilloscope and launches server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    # Instantiate driver
    tektronix_logger = kwargs['logger']
    tektronix_driver = tektronix_tds2004C.Driver(
        gpib_address=kwargs['device_id'],
        logger=tektronix_logger
    )
    

    # Instantiate server
    tektronix_service = Service()
    tektronix_service.assign_module(module=tektronix_driver)
    tektronix_service.assign_logger(logger=tektronix_logger)
    tektronix_server = GenericServer(
        service=tektronix_service,
        host=get_ip(),
        port=kwargs['port']
    )

    tektronix_server.start()
Esempio n. 4
0
def launch(**kwargs):
    """ Connects to ANC3000 and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    device_config = load_device_config('anc300',
                                       kwargs['config'],
                                       logger=kwargs['logger'])
    telnet_config = device_config['telnet_config']

    anc300 = ANC300(host=telnet_config['host'],
                    port=telnet_config['port'],
                    query_delay=device_config['query_delay'],
                    passwd=telnet_config['passwd'],
                    limits=device_config['limits'],
                    logger=kwargs['logger'])

    anc300_service = Service()
    anc300_service.assign_module(module=anc300)
    anc300_service.assign_logger(logger=kwargs['logger'])
    anc300_server = GenericServer(service=anc300_service,
                                  host=get_ip(),
                                  port=kwargs['port'])
    anc300_server.start()
Esempio n. 5
0
def launch(**kwargs):
    """ Connects to a NI DAQ as staticline

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    staticline_logger = kwargs['logger']
    daq = nidaqmx.Driver(device_name=NI_DEVICE_NAME, logger=staticline_logger)

    test_staticline = staticline.Driver(
        name='Green Imaging Laser',
        logger=kwargs['logger'],
        hardware_module=daq,
        ao_output='ao2',
        down_voltage=0,
        up_voltage=3.3,
    )

    # Instantiate Server
    # Staticline server
    staticline_service = Service()
    staticline_service.assign_module(module=test_staticline)
    staticline_service.assign_logger(logger=staticline_logger)
    staticline_service_server = GenericServer(service=staticline_service,
                                              host=get_ip(),
                                              port=kwargs['port'])

    staticline_service_server.start()
Esempio n. 6
0
def launch(**kwargs):
    """ Connects to TP Link HS103 Smart Plug

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :device_id: (int) Location of Smart plug (e.g. Powermeter Front Smart Plug)
    """

    logger=kwargs['logger']
    config = load_device_config('tp_link_hs103', kwargs['config'])
    smart_plug = Driver(
        logger=kwargs['logger'],
        channels=config['channels']
    )

    # Instantiate Server
    smart_plug_service = Service()
    smart_plug_service.assign_module(module=smart_plug)
    smart_plug_service.assign_logger(logger=kwargs['logger'])
    smart_plug_server = GenericServer(
        service=smart_plug_service,
        host=get_ip(),
        port=kwargs['port']
    )
    smart_plug_server.start()
Esempio n. 7
0
def launch(**kwargs):
    """ Connects to a NI DAQ as staticline

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    staticline_logger = kwargs['logger']

    # Instantiate HDAWG driver.
    hd = zi_hdawg.Driver(dev_id, logger=staticline_logger)

    aom = staticline.Driver(
        name='AOM',
        logger=staticline_logger,
        hardware_module=hd,
        DIO_bit=30,
    )

    # Instantiate Server
    # Staticline server
    staticline_service = Service()
    staticline_service.assign_module(module=aom)
    staticline_service.assign_logger(logger=staticline_logger)
    staticline_service_server = GenericServer(service=staticline_service,
                                              host=get_ip(),
                                              port=kwargs['port'])

    staticline_service_server.start()
Esempio n. 8
0
def launch(**kwargs):
    """ Connects to SI TT and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    if not IMPORT_STATUS:
        msg_str = 'Please make sure Swabian Instruments drivers are installed on this machine.'
        raise ModuleNotFoundError(msg_str)

    TT.setTimeTaggerChannelNumberScheme(TT.TT_CHANNEL_NUMBER_SCHEME_ONE)

    # Connect to the device, otherwise instantiate virtual connection
    try:
        tagger = TT.createTimeTagger()
    except RuntimeError:
        kwargs['logger'].warn('Failed to connect to Swabian Instruments Time Tagger.'
                              ' Instantiating virtual device instead')
        tagger = TT.createTimeTaggerVirtual()

    try:
        config = kwargs['config']
        config = load_device_config('si_tt', config, logger=kwargs['logger'])
    except:
        config = None

    # if config is None:
    #     try:
    #         config = load_device_config('si_tt', logger=kwargs['logger'])
    #     except:
    #         config = {}

    for channel, trig_level in config['triggers'].items():
        tagger.setTriggerLevel(int(channel), float(trig_level))

    cnt_trace_wrap = Wrap(
        tagger=tagger,
        logger=kwargs['logger']
    )

    # Instantiate Server
    cnt_trace_service = Service()
    cnt_trace_service.assign_module(module=cnt_trace_wrap)
    cnt_trace_service.assign_logger(logger=kwargs['logger'])
    cnt_trace_server = GenericServer(
        service=cnt_trace_service,
        host=get_ip(),
        port=kwargs['port']
    )
    cnt_trace_server.start()
Esempio n. 9
0
def launch(**kwargs):
    """ Connects to MCS2 and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    mcs2 = MCS2(logger=kwargs['logger'])
    mcs2_service = Service()
    mcs2_service.assign_module(module=mcs2)
    mcs2_service.assign_logger(logger=kwargs['logger'])
    mcs2_server = GenericServer(service=mcs2_service,
                                host=get_ip(),
                                port=kwargs['port'])
    mcs2_server.start()
Esempio n. 10
0
def launch(**kwargs):
    """ Launches a dummy hardware driver and instantiates server """

    log = kwargs['logger']
    log.info(f'Launching with config {kwargs["config"]}')
    config = load_device_config(
        os.path.basename(__file__)[:-3], kwargs['config'], log)

    dum = Dummy()
    log.info(f'Created dummy object with configuration parameters {config}')
    dum_service = ServiceBase()
    dum_service.assign_module(module=dum)
    dum_service.assign_logger(logger=log)
    dum_server = GenericServer(service=dum_service,
                               host=get_ip(),
                               port=kwargs['port'])
    dum_server.start()
Esempio n. 11
0
def launch(**kwargs):
    """ Connects to NI-daqMX card and launches server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    # Instantiate driver
    ni_daqmx_logger = kwargs['logger']
    try:
        ni_driver = nidaqmx_card.Driver(
            device_name=kwargs['device_id'],
            logger=ni_daqmx_logger
        )
    except AttributeError:
        try:
            config = load_config(kwargs['config'])
            ni_driver = nidaqmx_card.Driver(
                device_name=config['device'],
                logger=ni_daqmx_logger
            )
        except AttributeError:
            ni_daqmx_logger.error('Please provide valid config file')
            raise
        except OSError:
            ni_daqmx_logger.error(f'Did not find NI daqMX name {config["device"]}')
            raise
        except KeyError:
            ni_daqmx_logger.error('No device name provided. '
                                'Please make sure proper config file is provided')
            raise

    # Instantiate server
    ni_daqmx_service = Service()
    ni_daqmx_service.assign_module(module=ni_driver)
    ni_daqmx_service.assign_logger(logger=ni_daqmx_logger)
    ni_daqmx_server = GenericServer(
        service=ni_daqmx_service,
        host=get_ip(),
        port=kwargs['port']
    )

    ni_daqmx_server.start()
Esempio n. 12
0
def launch(**kwargs):

    # Instantiate driver
    zi_logger = kwargs['logger']

    device_id = load_device_config('zi_hdawg',
                                   kwargs['config'],
                                   logger=kwargs['logger'])['device_id']
    hd = Driver(device_id, zi_logger)

    # Instantiate server
    hd_service = Service()
    hd_service.assign_module(module=hd)
    hd_service.assign_logger(logger=zi_logger)
    hd_server = GenericServer(service=hd_service,
                              host=get_ip(),
                              port=kwargs['port'])

    hd_server.start()
Esempio n. 13
0
def launch(**kwargs):
    """ Connects to HWC T2220 (microwave source) and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Hittite server
    """
    config = kwargs['config']
    config = load_device_config('HMC_T2220', config, logger=kwargs['logger'])
    mw_source = ht.Driver(logger=kwargs['logger'],
                          gpib_address=config['device_id'])

    # Instantiate Server
    mw_service = Service()
    mw_service.assign_module(module=mw_source)
    mw_service.assign_logger(logger=kwargs['logger'])
    mw_server = GenericServer(service=mw_service,
                              host=get_ip(),
                              port=kwargs['port'])
    mw_server.start()
Esempio n. 14
0
def launch(**kwargs):
    """ Connects to spectrum analyzer and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the spectrum analyzer server
    """
    config = kwargs['config']
    config = load_device_config('CLD101x', config, logger=kwargs['logger'])
    il = laser.Driver(gpib_address=config['device_id'],
                      logger=kwargs['logger'])

    # Instantiate Server
    il_service = Service()
    il_service.assign_module(module=il)
    il_service.assign_logger(logger=kwargs['logger'])
    il_server = GenericServer(service=il_service,
                              host=socket.gethostbyname_ex(
                                  socket.gethostname())[2][0],
                              port=kwargs['port'])
    il_server.start()
Esempio n. 15
0
def launch(**kwargs):
    """ Connects to MPC320 instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    settings = load_device_config('thorlabs_mpc320',
                                  kwargs['config'],
                                  logger=kwargs['logger'])

    dev_num = settings['device_id']

    pol_paddle = Driver(device_num=int(dev_num), logger=kwargs['logger'])

    pol_paddle_service = Service()
    pol_paddle_service.assign_module(module=pol_paddle)
    pol_paddle_service.assign_logger(logger=kwargs['logger'])
    pol_paddle_service_server = GenericServer(service=pol_paddle_service,
                                              host=get_ip(),
                                              port=kwargs['port'])
    pol_paddle_service_server.start()
Esempio n. 16
0
def launch(**kwargs):
    """ Connects to HF WS7 Wavemeter and launches server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    # Instantiate Logger
    wavemeter_logger = kwargs['logger']

    # Instantiate Wavemeter object
    hf_wlm = Driver(logger=wavemeter_logger)

    # Instantiate Server
    wavemeter_service = Service()
    wavemeter_service.assign_module(module=hf_wlm)
    wavemeter_service.assign_logger(logger=wavemeter_logger)
    wavemeter_server = GenericServer(service=wavemeter_service,
                                     host=get_ip(),
                                     port=kwargs['port'])

    wavemeter_server.start()
Esempio n. 17
0
def launch(**kwargs):
    """ Connects to DIO breakout and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the DIO breakout server
        :config: (str) name of config file to us
    """

    device_config = load_device_config('dio_breakout',
                                       kwargs['config'],
                                       logger=kwargs['logger'])

    # Try to load settings
    if 'resource_name' in device_config:
        addr = device_config['resource_name']
    else:
        addr = device_config['device_id']

    # Try to connect
    try:
        dio = Driver(address=addr, logger=kwargs['logger'])

    # If it fails, prompt the user to enter GPIB address from resource list
    except VisaIOError:
        kwargs['logger'].error(
            f'Failed to connect to device at address {addr}')
        raise

    # Instantiate Service and server
    dio_service = Service()
    dio_service.assign_module(module=dio)
    dio_service.assign_logger(logger=kwargs['logger'])
    dio_server = GenericServer(service=dio_service,
                               host=get_ip(),
                               port=kwargs['port'])
    dio_server.start()
Esempio n. 18
0
def launch(**kwargs):
    """ Connects to PM320E and instantiates server

    :param kwargs: (dict) containing relevant kwargs
        :logger: instance of LogClient for logging purposes
        :port: (int) port number for the Cnt Monitor server
    """

    try:
        settings = load_device_config('thorlabs_pm320e',
                                      kwargs['config'],
                                      logger=kwargs['logger'])
    except KeyError:
        kwargs['logger'].warn('No config file was provided')

    try:
        pm = Driver(
            logger=kwargs['logger'],
            gpib_address=settings['device_id'],
        )

    # Handle error of wrong GPIB address by allowing user to select
    # NOTE: this will fail if used from the main script launcher, since script client
    # will automatically try to connect (even though server isn't launched)
    #
    # TLDR: if you want to use launch-control, please fill in GPIB variable with
    # the correct resource string
    except:
        kwargs['logger'].error('Please check GPIB address, could not connect')

    pm_service = Service()
    pm_service.assign_module(module=pm)
    pm_service.assign_logger(logger=kwargs['logger'])
    pm_server = GenericServer(service=pm_service,
                              host=get_ip(),
                              port=kwargs['port'])
    pm_server.start()
Esempio n. 19
0
def launch(**kwargs):
    """ Connects to toptica laser and launches server

    :param kwargs: (dict) containing relevant kwargs
    """

    # Instantiate driver
    toptica_logger = kwargs['logger']
    config = load_device_config('toptica_dlc_pro', kwargs['config'],
                                toptica_logger)

    dlc = DLC_Pro(host=config['host'],
                  port=int(config['port']),
                  logger=toptica_logger)

    # Instantiate server
    dlc_service = Service()
    dlc_service.assign_module(module=dlc)
    dlc_service.assign_logger(logger=toptica_logger)
    dlc_server = GenericServer(service=dlc_service,
                               host=get_ip(),
                               port=kwargs['port'])

    dlc_server.start()
Esempio n. 20
0
class Controller:
    """ Class for log system controller """

    LOGGER_UI = 'logger_remote'
    GUI_NAME = 'logger_GUI'

    # When kept as None, random port numbers will be used
    # use these values to override and set manual port numbers if desired
    LOG_PORT = None
    GUI_PORT = None

    def __init__(self, proxy=False, master=False, staticproxy=False):
        """ Initializes launch control GUI """

        self.operating_system = get_os()
        self.app = QtWidgets.QApplication(sys.argv)
        self.app.setWindowIcon(
            QtGui.QIcon(
                os.path.join(os.path.dirname(os.path.realpath(__file__)),
                             'devices.ico')))
        # Instantiate GUI application
        if self.operating_system == 'Windows':
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                'pylabnet')

        self.main_window = LaunchWindow(self.app,
                                        self,
                                        gui_template=self.LOGGER_UI)
        self.main_window.stop_button.clicked.connect(self._kill)
        if self.operating_system not in ['Linux', 'Windows']:
            raise UnsupportedOSException
        try:
            if sys.argv[1] == '-m' or master:
                self.master = True
            else:
                self.master = False
        except IndexError:
            if master:
                self.master = True
            else:
                self.master = False

        try:
            if sys.argv[1] == '-p' or proxy:
                self.proxy = True
            else:
                self.proxy = False
        except IndexError:
            if proxy:
                self.proxy = True
            else:
                self.proxy = False

        try:
            if sys.argv[1] == '-sp' or staticproxy:
                self.staticproxy = True
            else:
                self.staticproxy = False
        except IndexError:
            if staticproxy:
                self.staticproxy = True
            else:
                self.staticproxy = False

        self.host = get_ip()
        self.update_index = 0

        # Retrieve static port info.
        if self.master:
            try:
                static_proxy_dict = load_config('static_proxy')
            except:
                print('No config found named static_proxy.json')
                time.sleep(10)
                raise
            self.log_port = static_proxy_dict['master_log_port']
            self.gui_port = static_proxy_dict['master_gui_port']
            hide_console()
        elif self.proxy:
            popup = ParameterPopup(host=str, log_port=str, gui_port=str)
            self.waiting_flag = True
            popup.parameters.connect(self.fill_parameters)
            while self.waiting_flag:
                self.app.processEvents()
        elif self.staticproxy:
            try:
                static_proxy_dict = load_config('static_proxy')
            except:
                print('No config found named static_proxy.json')
                time.sleep(10)
                raise
            self.host = static_proxy_dict['master_ip']
            self.log_port = static_proxy_dict['master_log_port']
            self.gui_port = static_proxy_dict['master_gui_port']
            self.proxy = True
            hide_console()
        else:
            self.log_port = self.LOG_PORT
            self.gui_port = self.GUI_PORT

        self.log_service = None
        self.log_server = None
        self.gui_client = None
        self.gui_logger = None
        self.gui_service = None
        self.gui_server = None
        self.client_list = {}
        self.port_list = {}
        self.script_list = {}
        self.client_data = {}
        self.disconnection = False
        self.debug = False
        self.debug_level = None
        self.autoscroll_off = False
        # date string is None if not logging to file, and gives today's date if logging to file.
        # For day-chopping purposes
        self.logfile_date_str = None
        self.filenamepath = None
        self.MAX_LOG_FILE_SIZE = 5000000  # 5MB
        self.last_seen_buffer = ""

        # setting selection mode for server list to multi-select
        self.main_window.client_list.setSelectionMode(
            QtWidgets.QAbstractItemView.ExtendedSelection)

    def fill_parameters(self, params):
        """ Called when parameters have been entered into a popup """

        self.host = params['host']
        self.log_port = params['log_port']
        self.gui_port = params['gui_port']
        self.waiting_flag = False

    def start_gui_server(self):
        """ Starts the launch controller GUI server, or connects to the server and updates GUI"""

        module_str = ''
        if self.proxy:
            module_str = '_proxy'
        # connect to the logger
        try:
            self.gui_logger = LogClient(host=self.host,
                                        port=self.log_port,
                                        module_tag=self.GUI_NAME + module_str,
                                        ui=self.LOGGER_UI)
        except ConnectionRefusedError:
            self.main_window.terminal.setText(
                'Failed to connect to master. Shutting down')
            self.main_window.force_update()
            time.sleep(10)
            raise

        # if lab name is specified: add to gui_logger
        try:
            lab_name_dict = load_config("lab_name")
            lab_name = lab_name_dict['lab_name']
        except:
            lab_name = 'NO_LAB'

        self.gui_logger.update_data(data=dict(lab_name=lab_name))

        # Instantiate GUI server and update GUI with port details
        self.gui_service = Service()
        self.gui_service.assign_module(module=self.main_window)
        self.gui_service.assign_logger(logger=self.gui_logger)
        if self.gui_port is None:
            self.gui_server, self.gui_port = create_server(
                self.gui_service, logger=self.gui_logger, host=get_ip())
            my_port = self.gui_port
            self.main_window.gui_label.setText(f'GUI Port: {my_port}')
        elif self.proxy:
            self.gui_server, my_port = create_server(self.gui_service,
                                                     logger=self.gui_logger,
                                                     host=get_ip())
            self.main_window.gui_label.setText(
                f'Master (Local) GUI Port: {self.gui_port} ({my_port})')
        else:
            try:
                self.gui_server = GenericServer(service=self.gui_service,
                                                host=get_ip(),
                                                port=self.gui_port)
                my_port = self.gui_port
                self.main_window.gui_label.setText(f'GUI Port: {my_port}')
            except ConnectionRefusedError:
                self.gui_logger.error(
                    f'Failed to instantiate GUI Server at port {self.gui_port}'
                )
                raise
        self.gui_server.start()
        self.gui_logger.update_data(data=dict(port=my_port))

        if self.proxy:
            # Connect to the GUI server
            try:
                self.gui_client = Client(host=self.host, port=self.gui_port)
            except ConnectionRefusedError:
                self.gui_logger.error(
                    f'Failed to connect to GUI Server with IP address: {self.host}, '
                    f'Port: {self:gui_port}')
                raise

            # Now update GUI to mirror clients
            self._copy_master()

            # Get the latest update index
            buffer = self.gui_client.get_text('buffer')
            try:
                self.update_index = int(
                    re.findall(r'\d+',
                               re.findall(r'!~\d+~!', buffer)[-1])[0])
            except IndexError:
                self.update_index = 0

            self.gui_service = Service()
            self.gui_service.assign_module(module=self.main_window)
            self.gui_service.assign_logger(logger=self.gui_logger)

        else:

            # Update internal attributes and add to list of log clients
            self.client_list[self.GUI_NAME] = QtWidgets.QListWidgetItem(
                self.GUI_NAME)
            self.port_list[self.GUI_NAME] = [
                port for port in self.log_server._server.clients
            ][0]
            self.main_window.client_list.addItem(
                self.client_list[self.GUI_NAME])
            self.client_list[self.GUI_NAME].setToolTip(
                dict_to_str(self.log_service.client_data[self.GUI_NAME]))
            self.client_data[self.GUI_NAME +
                             module_str] = self.log_service.client_data[
                                 self.GUI_NAME]

    def update_terminal(self, text):
        """ Updates terminal output on GUI """

        self.main_window.terminal.append(text)
        if not self.autoscroll_off:
            try:
                self.main_window.terminal.moveCursor(QtGui.QTextCursor.End)
            except TypeError:
                pass
        # Update buffer terminal
        buffer_str = f'!~{self.update_index}~!{text}'
        self.main_window.buffer_terminal.append(buffer_str)
        self.update_index += 1

    def check_disconnection(self, text):
        """ Checks if a client has disconnected and raises a flag if so"""

        if 'Client disconnected' in text or self.disconnection:
            self.disconnection = True

    def disconnect(self):
        """ Handles case where client has disconnected """

        to_del = [
            client for (client, port) in self.port_list.items()
            if port not in self.log_server._server.clients
        ]
        for client in to_del:
            print('[INFO] {} disconnected at {}'.format(
                client, time.strftime("%Y-%m-%d, %H:%M:%S", time.gmtime())))
            self.main_window.client_list.takeItem(
                self.main_window.client_list.row(self.client_list[client]))
            del self.client_list[client]
            del self.port_list[client]
            del self.log_service.client_data[client]
            del self.client_data[client]
            self.disconnection = False

    def update_connection(self):
        """ Checks if new/updated connections have been made and updates accordingly"""

        # Figure out ports/clients to add
        port_to_add = [
            port for port in self.log_server._server.clients
            if port not in self.port_list.values()
        ]
        client_to_add = [
            client for client in self.log_service.client_data
            if client not in self.client_list
        ]

        # Add client and update relevant directories + GUI
        if len(client_to_add) > 0:
            client = client_to_add[0]
            self.client_list[client] = QtWidgets.QListWidgetItem(client)
            self.main_window.client_list.addItem(self.client_list[client])
            try:
                self.main_window.client_list.moveCursor(QtGui.QTextCursor.End)
            except TypeError:
                pass
            self.client_list[client].setToolTip(
                dict_to_str(self.log_service.client_data[client]))
            if len(port_to_add) > 0:
                self.port_list[client] = port_to_add[0]
            self.client_data[client] = self.log_service.client_data[client]

        # Check for updates to client data
        while len(self.log_service.data_updated) > 0:
            self.client_list[self.log_service.data_updated[0]].setToolTip(
                dict_to_str(self.log_service.client_data[
                    self.log_service.data_updated[0]]))
            del self.log_service.data_updated[0]

    def start_logger(self):
        """ Starts the log server """

        self.log_service = LogService()
        if self.LOG_PORT is None and not self.master:
            self.log_server, self.log_port = create_server(self.log_service,
                                                           host=get_ip())
        else:
            try:
                self.log_server = GenericServer(service=self.log_service,
                                                host=get_ip(),
                                                port=self.log_port)
            except ConnectionRefusedError:
                print(
                    f'Failed to insantiate Log Server at port {self.LOG_PORT}')
                raise
        self.log_server.start()

        self.log_service.logger.info('log service succesfully started')

    def initialize_gui(self):
        """ Initializes basic GUI display """

        ip_str, ip_str_2, log_str = '', '', ''
        if self.master:
            self.main_window.setWindowTitle('Launch Control (Master)')
        if self.proxy:
            if self.staticproxy:
                self.main_window.setWindowTitle('Launch Control (Staticproxy)')
            else:
                self.main_window.setWindowTitle('Launch Control (Proxy)')
            ip_str = 'Master (Local) '
            ip_str_2 = f' ({get_ip()})'
            log_str = 'Master'
        self.main_window.ip_label.setText(f'{ip_str}IP Address: {self.host}' +
                                          ip_str_2)
        self.main_window.logger_label.setText(
            f'{log_str} Logger Port: {self.log_port}')

        if self.proxy:
            self.main_window.terminal.setText(
                'Connected to master Log Server. \n')
        self.main_window.terminal.setText(
            'Log messages will be displayed below \n')
        self.main_window.buffer_terminal.document().setMaximumBlockCount(1000)

        # Assign widgets for remote access
        self.main_window.assign_container('client_list', 'clients')
        self.main_window.assign_label('buffer_terminal', 'buffer')
        self.main_window.assign_event_button('debug_radio_button', 'debug')

        # Hide some buttons
        self.main_window.file_viewer.setHidden(True)
        self.main_window.logfile_status_button.setHidden(True)
        self.main_window.debug_label.setHidden(True)
        self.main_window.debug_comboBox.setHidden(True)
        self.main_window.logfile_status_button.setHidden(True)
        self.main_window.log_previous.setHidden(True)
        self.main_window.logfile_status_indicator.setEnabled(False)

        # Configure list of scripts to run and clicking actions
        self._load_scripts()
        self._configure_clicks()
        self._configure_client_search()
        self._configure_lab_name_select()
        self._configure_debug()
        self._configure_debug_combo_select()
        self._configure_logfile()
        self._configure_logging()
        self._configure_autoscroll_off()

        self.main_window.force_update()

    def update_proxy(self, new_msg):
        """ Updates the proxy with new content using the buffer terminal continuously"""

        # Remove the !~ bookmark from the message
        self.main_window.terminal.append(re.sub(r'!~\d+~!', '', new_msg))
        if not self.autoscroll_off:
            try:
                self.main_window.terminal.moveCursor(QtGui.QTextCursor.End)
            except TypeError:
                pass

        # New update index is the last !~ index found in the message
        indices_found = re.findall(r'!~\d+~!', new_msg)
        if len(indices_found) != 0:
            self.update_index = int(re.findall(r'\d+', indices_found[-1])[0])
        else:
            self.update_index = None

    def kill_servers(self):
        """ Kills all servers connected to the logger, including the Log GUI and Log Server"""

        client_data = copy.deepcopy(self.client_data)
        del client_data['logger_GUI']

        for server_data in client_data.values():
            if 'port' in server_data:
                stop_client = ClientBase(host=server_data['ip'],
                                         port=server_data['port'])
                stop_client.close_server()
        self.gui_server.stop()
        self.log_server.stop()

    def update(self, text):
        """ Runs an update when new text comes through """

        self.main_window.configure_widgets()
        self.main_window.update_widgets()

        #Check for disconnection events
        self.check_disconnection(text)

        # Handle new connections
        self.update_connection()

        # Update terminal
        self.update_terminal(text)

        # Chop log file if date has changed
        self.chop_log_file()

        if self.disconnection:
            self.disconnect()

    def chop_log_file(self):
        """ Checks if date has changed, and chops logfile accordingly"""

        if self.logfile_date_str is not None:
            # if date has changed, move to new log file with new date
            if self.logfile_date_str != datetime.now().strftime("%Y_%m_%d"):
                self.log_service.logger.info('Starting new logging file!')
                self.start_stop_logging(master_log=True)
            if os.stat(self.filenamepath).st_size > self.MAX_LOG_FILE_SIZE:
                self.log_service.logger.info('Starting new logging file!')
                self.start_stop_logging(master_log=True)

    def _configure_client_search(self):
        self.main_window.client_search.textChanged.connect(
            self._update_displayed_client_list)

    def _configure_lab_name_select(self):
        self.main_window.lab_name_select.currentIndexChanged.connect(
            self._update_displayed_client_list)

    def _configure_clicks(self):
        """ Configures what to do upon clicks """

        self.main_window.close_server.pressed.connect(self._stop_server)

    def _update_displayed_client_list(self):

        search_str = self.main_window.client_search.text()
        lab_name = self.main_window.lab_name_select.currentText()

        clients = self.gui_client.get_container_info('clients')

        self.main_window.client_list.clear()
        self.client_list.clear()

        if lab_name == "ALL LABS":  # if ALL LABS is selected, don't filter by lab name
            if search_str != "":
                for client, info in clients.items():
                    self.client_list[client] = QtWidgets.QListWidgetItem(
                        client)
                    # look for clients that have name or ip address containing search string
                    if search_str in client or search_str in self.client_data[
                            client]['ip']:
                        self.main_window.client_list.addItem(
                            self.client_list[client])
                    self.client_list[client].setToolTip(info)
            else:  # if search string is empty, don't use it to filter clients
                for client, info in clients.items():
                    self.client_list[client] = QtWidgets.QListWidgetItem(
                        client)
                    self.main_window.client_list.addItem(
                        self.client_list[client])
                    self.client_list[client].setToolTip(info)

        else:  # filter by lab name
            if search_str != "":
                for client, info in clients.items():
                    self.client_list[client] = QtWidgets.QListWidgetItem(
                        client)
                    # look for clients that have name or ip address containing search string, and that have the selected lab name
                    if (search_str in client
                            or search_str in self.client_data[client]['ip']
                        ) and (self.client_data[client]['lab_name']
                               == lab_name):
                        self.main_window.client_list.addItem(
                            self.client_list[client])
                    self.client_list[client].setToolTip(info)
            else:  # if search string is empty, don't use it to filter clients
                for client, info in clients.items():
                    self.client_list[client] = QtWidgets.QListWidgetItem(
                        client)
                    # look for clients that have the selected lab name
                    if self.client_data[client]['lab_name'] == lab_name:
                        self.main_window.client_list.addItem(
                            self.client_list[client])
                    self.client_list[client].setToolTip(info)

    def _stop_server(self):
        """ Stops the highlighted server, if applicable """

        # Retrieve all selected servers.
        clients_to_stop = [
            client.text()
            for client in self.main_window.client_list.selectedItems()
        ]

        for client_to_stop in clients_to_stop:
            server_data = self.client_data[client_to_stop]
            if 'port' in server_data:
                try:
                    stop_client = ClientBase(host=server_data['ip'],
                                             port=server_data['port'])
                    stop_client.close_server()
                except:
                    self.gui_logger.warn(
                        f'Failed to shutdown server {client_to_stop}'
                        f'on host: {server_data["ip"]}, port: {server_data["port"]}'
                    )
                    self.gui_logger.info(
                        'Attempting to remove from LogClients manually')
                    self._close_dangling(client_to_stop)
            else:
                self._close_dangling(client_to_stop)

    def _close_dangling(self, client_to_stop):

        # Cannot connect to the server and close, must remove.
        # WARNING: might result in dangling threads

        try:
            client_port_to_stop = self.port_list[client_to_stop]
            port_found = True
        except KeyError:
            port_found = False

        if port_found and client_port_to_stop in self.log_server._server.clients:
            c = self.port_list[client_to_stop]
            c.close()
            closing(c)
            self.log_server._server.clients.discard(c)
            self.main_window.client_list.takeItem(
                self.main_window.client_list.row(
                    self.client_list[client_to_stop]))
            del self.port_list[client_to_stop]
            del self.client_list[client_to_stop]
            del self.log_service.client_data[client_to_stop]
            del self.client_data[client_to_stop]
            self.gui_logger.info(f'Client disconnected: {client_to_stop}')

        # If we can't find the client connected to the server, just remove it
        else:
            self.gui_logger.warn(
                f'No matching client connected to LogServer: {client_to_stop}')
            try:

                # The following two member variables don't exist for a proxy.
                if not self.proxy:
                    self.main_window.client_list.takeItem(
                        self.main_window.client_list.row(
                            self.client_list[client_to_stop]))
                    del self.port_list[client_to_stop]
                    del self.log_service.client_data[client_to_stop]
                    del self.client_list[client_to_stop]
                    del self.client_data[client_to_stop]
                else:
                    self.gui_client.remove_client_list_entry(client_to_stop)
                self.gui_logger.info(
                    f'Hard kill of {client_to_stop} successfull.')

            except:
                pass

    def _device_clicked(self, index):
        """ Configures behavior for device double click

        :param index: (QModelIndex) index of file clicked on
        """

        # clear the client search bar and display all clients
        self.main_window.client_search.setText("")
        #self._search_clients()

        filepath = self.main_window.devices.model().filePath(index)

        # Check if it is an actual config file
        if not os.path.isdir(filepath):

            # Find the name of the server and device config file
            device_server = os.path.basename(os.path.dirname(filepath))
            device_config = os.path.basename(filepath)[:-5]

            self.gui_logger.info(f'Launching device {device_server} '
                                 f'with configuration {device_config}')

            # Initial configurations: All flags down.
            server_debug_flag = '0'

            # Raise flags if selected in combobox
            if self.debug and self.debug_level == "pylabnet_server":
                server_debug_flag = '1'

            server_port = np.random.randint(1024, 49151)
            launch_device_server(server=device_server,
                                 dev_config=device_config,
                                 log_ip=self.host,
                                 log_port=self.log_port,
                                 server_port=server_port,
                                 debug=server_debug_flag,
                                 logger=self.gui_logger)

    def _script_clicked(self, index):
        """ Configures behavior for script double click

        :param index: (QModelIndex) index of file clicked on
        """

        # clear the client search bar and display all clients
        self.main_window.client_search.setText("")
        #self._search_clients()

        filepath = self.main_window.scripts.model().filePath(index)

        # Check if it is an actual config file
        if not os.path.isdir(filepath):

            # Find the name of the config file
            script_name = os.path.basename(os.path.dirname(filepath))
            script_config = os.path.basename(filepath)[:-5]

            self.gui_logger.info(f'Launching device {script_name} '
                                 f'with configuration {script_config}')

            # Initial configurations: All flags down.
            debug_flag, server_debug_flag = '0', '0'

            # Raise flags if selected in combobox
            if self.debug:
                if self.debug_level == "launcher":
                    debug_flag = '1'
                elif self.debug_level == "pylabnet_server":
                    server_debug_flag = '1'

            # # Build client list cmdline arg
            # client_index = 1
            # bash_cmd = ''
            # for client in self.client_list:
            #     bash_cmd += ' --client{} {} --ip{} {}'.format(
            #         client_index, remove_spaces(client), client_index, self.client_data[client]['ip']
            #     )

            #     # Add device ID of client's corresponding hardware, if applicable
            #     if 'device_id' in self.client_data[client]:
            #         bash_cmd += ' --device_id{} {}'.format(client_index, self.client_data[client]['device_id'])

            #     # Add port of client's server, if applicable
            #     if 'port' in self.client_data[client]:
            #         bash_cmd += ' --port{} {}'.format(client_index, self.client_data[client]['port'])

            #     # If this client has relevant .ui file, pass this info
            #     if 'ui' in self.client_data[client]:
            #         bash_cmd += ' --ui{} {}'.format(client_index, self.client_data[client]['ui'])

            #     client_index += 1

            launch_script(script=script_name,
                          config=script_config,
                          log_ip=self.host,
                          log_port=self.log_port,
                          debug_flag=debug_flag,
                          server_debug_flag=server_debug_flag,
                          num_clients=len(self.client_list),
                          logger=self.gui_logger)

    def _load_scripts(self):
        """ Loads all relevant scripts/devices from filesystem"""

        # Load scripts with configuraitons
        script_dir = os.path.join(get_config_directory(), 'scripts')
        if os.path.isdir(script_dir):
            model = QtWidgets.QFileSystemModel()
            model.setRootPath(script_dir)
            self.main_window.scripts.setModel(model)
            self.main_window.scripts.setRootIndex(model.index(script_dir))
            self.main_window.scripts.hideColumn(1)
            self.main_window.scripts.hideColumn(2)
            self.main_window.scripts.hideColumn(3)
        self.main_window.scripts.doubleClicked.connect(self._script_clicked)

        # Load device config files
        device_dir = os.path.join(get_config_directory(), 'devices')
        if os.path.isdir(device_dir):
            model = QtWidgets.QFileSystemModel()
            model.setRootPath(device_dir)
            self.main_window.devices.setModel(model)
            self.main_window.devices.setRootIndex(model.index(device_dir))
            self.main_window.devices.hideColumn(1)
            self.main_window.devices.hideColumn(2)
            self.main_window.devices.hideColumn(3)
        self.main_window.devices.doubleClicked.connect(self._device_clicked)

    def _copy_master(self):
        """ Updates the GUI to copy the GUI of the master GUI server """

        # Get a dictionary of all client names and tooltip info
        clients = self.gui_client.get_container_info('clients')

        # Update the proxy GUI to reflect the client list of the main GUI
        for client, info in clients.items():
            self.client_list[client] = QtWidgets.QListWidgetItem(client)
            self.main_window.client_list.addItem(self.client_list[client])
            self.client_list[client].setToolTip(info)

            # Add client data
            self.client_data[client] = {}
            if 'ip: ' in info:
                self.client_data[client]['ip'] = info.split('ip: ')[1].split(
                    '\n')[0]
            if 'timestamp: ' in info:
                self.client_data[client]['timestamp'] = info.split(
                    'timestamp: ')[1].split('\n')[0]
            if 'ui: ' in info:
                self.client_data[client]['ui'] = info.split('ui: ')[1].split(
                    '\n')[0]
            if 'port: ' in info:
                self.client_data[client]['port'] = info.split(
                    'port: ')[1].split('\n')[0]
            if 'device_id: ' in info:
                self.client_data[client]['device_id'] = info.split(
                    'device_id: ')[1].split('\n')[0]
            if 'lab_name: ' in clients[client]:
                self.client_data[client]['lab_name'] = clients[client].split(
                    'lab_name: ')[1].split('\n')[0]
            else:  # if no lab name is specified
                self.client_data[client]['lab_name'] = "NO_LAB"

    def _pull_connections(self):
        """ Updates the proxy's client list """

        # Get a dictionary of all client names and tooltip info
        clients = self.gui_client.get_container_info('clients')

        # Update the proxy GUI to reflect the client list of the main GUI
        add_clients = list(set(clients.keys()) - set(self.client_list.keys()))
        remove_clients = list(
            set(self.client_list.keys()) - set(clients.keys()))
        other_clients = list(
            set(clients.keys()) - set(add_clients) - set(remove_clients))

        # Add clients
        for client in add_clients:
            self.client_list[client] = QtWidgets.QListWidgetItem(client)
            self.main_window.client_list.addItem(self.client_list[client])
            self.client_list[client].setToolTip(clients[client])

            # Add client data
            self.client_data[client] = {}
            print('Client: ' + client)
            if 'ip: ' in clients[client]:
                self.client_data[client]['ip'] = clients[client].split(
                    'ip: ')[1].split('\n')[0]
            if 'timestamp: ' in clients[client]:
                self.client_data[client]['timestamp'] = clients[client].split(
                    'timestamp: ')[1].split('\n')[0]
            if 'ui: ' in clients[client]:
                self.client_data[client]['ui'] = clients[client].split(
                    'ui: ')[1].split('\n')[0]
            if 'port: ' in clients[client]:
                self.client_data[client]['port'] = clients[client].split(
                    'port: ')[1].split('\n')[0]
            if 'device_id: ' in clients[client]:
                self.client_data[client]['device_id'] = clients[client].split(
                    'device_id: ')[1].split('\n')[0]
            if 'lab_name: ' in clients[client]:
                self.client_data[client]['lab_name'] = clients[client].split(
                    'lab_name: ')[1].split('\n')[0]
            else:  # if no lab name is specified
                self.client_data[client]['lab_name'] = "NO_LAB"

        # Remove clients
        for client in remove_clients:
            self.main_window.client_list.takeItem(
                self.main_window.client_list.row(self.client_list[client]))
            del self.client_list[client]

        # Update any other changes
        for client in other_clients:
            if self.client_list[client].toolTip() != clients[client]:
                self.client_list[client].setToolTip(clients[client])
                if 'ip: ' in clients[client]:
                    self.client_data[client]['ip'] = clients[client].split(
                        'ip: ')[1].split('\n')[0]
                if 'timestamp: ' in clients[client]:
                    self.client_data[client]['timestamp'] = clients[
                        client].split('timestamp: ')[1].split('\n')[0]
                if 'ui: ' in clients[client]:
                    self.client_data[client]['ui'] = clients[client].split(
                        'ui: ')[1].split('\n')[0]
                if 'port: ' in clients[client]:
                    self.client_data[client]['port'] = clients[client].split(
                        'port: ')[1].split('\n')[0]
                if 'device_id: ' in clients[client]:
                    self.client_data[client]['device_id'] = clients[
                        client].split('device_id: ')[1].split('\n')[0]
                if 'lab_name: ' in clients[client]:
                    self.client_data[client]['lab_name'] = clients[
                        client].split('lab_name: ')[1].split('\n')[0]
                else:  # if no lab name is specified
                    self.client_data[client]['lab_name'] = "NO_LAB"

    def _configure_autoscroll_off(self):
        self.main_window.autoscroll_off_check.toggled.connect(
            self._update_autoscroll_setting)

    # Defines what to do if debug radio button is clicked.
    def _configure_debug(self):
        self.main_window.debug_radio_button.toggled.connect(
            self._update_debug_settings)

    def _configure_logging(self):
        """ Defines what to do if the Start/Stop Logging button is clicked """
        self.main_window.logfile_status_button.toggled.connect(
            lambda: self.start_stop_logging(master_log=False))

    def _configure_logfile(self):
        """ Defines what to do if the logfile radio button is clicked """
        self.main_window.log_file_button.toggled.connect(
            self._update_logfile_status)

    # Defines what to do if combobox is changed.
    def _configure_debug_combo_select(self):
        self.main_window.debug_comboBox.currentIndexChanged.connect(
            self._update_debug_level)

    def _update_debug_settings(self):
        if self.main_window.debug_radio_button.isChecked():
            self.debug = True

            # Enable and show combobox.
            self.main_window.debug_comboBox.setEnabled(True)
            self.main_window.debug_label.setHidden(False)
            self.main_window.debug_comboBox.setHidden(False)

        else:
            self.debug = False
            # Disable and hide combobox.
            self.main_window.debug_comboBox.setEnabled(False)
            self.main_window.debug_label.setHidden(True)
            self.main_window.debug_comboBox.setHidden(True)

        # Update debug level.
        self._update_debug_level()

    def _update_logfile_status(self):
        """ Updates the status of whether or not we are using a logfile """
        if self.main_window.log_file_button.isChecked():

            # Enable and show file browser
            self.main_window.file_viewer.setEnabled(True)
            self.main_window.file_viewer.setHidden(False)
            self.main_window.logfile_status_button.setEnabled(True)
            self.main_window.logfile_status_button.setHidden(False)
            self.main_window.log_previous.setEnabled(True)
            self.main_window.log_previous.setHidden(False)

            # Assign a file system model if we're not already logging
            if not self.main_window.logfile_status_button.isChecked():
                model = QtWidgets.QFileSystemModel()
                model.setRootPath(QtCore.QDir.rootPath())
                self.main_window.file_viewer.setModel(model)
                self.main_window.file_viewer.setRootIndex(
                    model.index(QtCore.QDir.homePath()))
                self.main_window.file_viewer.setColumnWidth(0, 200)

        else:

            # Disable and hide file browser
            self.main_window.file_viewer.setHidden(True)
            self.main_window.file_viewer.setEnabled(False)
            self.main_window.logfile_status_button.setHidden(True)
            self.main_window.logfile_status_button.setEnabled(False)
            self.main_window.log_previous.setEnabled(False)
            self.main_window.log_previous.setHidden(True)

    def _update_debug_level(self, i=0):
        # Set debug level according to combo-box selection.
        # Levels are:
        # pylabnet_server, pylabnet_gui, launcher
        self.debug_level = self.main_window.debug_comboBox.currentText()

    def _update_autoscroll_setting(self):
        if self.main_window.autoscroll_off_check.isChecked():
            self.autoscroll_off = True
        else:
            self.autoscroll_off = False

    def _kill(self):
        """ Kills launch control and all child servers if master """

        if not self.proxy:
            self.kill_servers()

        self.main_window.close()

    def start_stop_logging(self, master_log=False):
        """ Starts or stops logging to file depending on situation

        :master_log: (bool) If True, this function is called as initial setup function of
            filesaving for the master launch control. In this case a log path as specified
            in the config file is chosen.
        """

        # check if there's already an open log file and close it
        if self.logfile_date_str is not None:
            self.log_service.stop_latest_logfile()

        if self.main_window.logfile_status_button.isChecked() or master_log:

            date_str = datetime.now().strftime("%Y_%m_%d")
            time_str = datetime.now().strftime("%H_%M_%S")

            # Actually start logging
            filename = f'logfile_{time_str}'

            # Get logging file from json.
            filepath = None
            if master_log:
                try:
                    config_dict = load_config('static_proxy')
                    filepath = config_dict['logger_path']
                except:
                    self.main_window.terminal.setText(
                        'Critical error: '
                        'no logger_path found in static_proxy.json')
                    self.main_window.force_update()
                    time.sleep(10)
                    raise
            # Or from filepath selector.
            else:
                filepath = self.main_window.file_viewer.model().filePath(
                    self.main_window.file_viewer.selectionModel().currentIndex(
                    ))

            try:
                self.log_service.add_logfile(name=filename, dir_path=filepath)
            except Exception as error_msg:
                print(
                    f'Failed to start logging to file {os.path.join(filepath, filename)}.\n{error_msg}'
                )

            self.log_service.logger.info(
                f'Started logging to file {os.path.join(filepath, filename)}.')

            # Change button color and text
            self.main_window.logfile_status_button.setStyleSheet(
                "background-color: red")
            self.main_window.logfile_status_button.setText(
                'Stop logging to file')
            self.main_window.logfile_status_indicator.setChecked(True)

            # Add previous text to logfile
            if self.main_window.log_previous.isChecked():
                self.log_service.logger.info(
                    f'Previous log terminal content: \n{self.main_window.terminal.toPlainText()}'
                    f'\n---------------------------')

            # Pass current date of logfile for day-chopping purposes
            self.logfile_date_str = date_str

            # pass log file name and path to access filesize for chopping purposes
            self.filenamepath = config_dict[
                'logger_path'] + '\\' + date_str[:4] + '\\' + date_str[
                    5:7] + '\\' + date_str[8:] + '\\logfile_' + time_str

        else:

            # Change button color and text
            self.main_window.logfile_status_button.setStyleSheet(
                "background-color: green")
            self.main_window.logfile_status_button.setText(
                'Start logging to file')
            self.main_window.logfile_status_indicator.setChecked(False)

            # Actually stop logging
            self.log_service.stop_latest_logfile()

            # Set date string to None so that logfile does not get updated anymore
            self.logfile_date_str = None