Skip to content
Snippets Groups Projects
main.py 4.99 KiB
Newer Older
Lorenz Wührl's avatar
Lorenz Wührl committed
import sys
from time import sleep, time
from serial import Serial
from serial.tools.list_ports import comports

from logging import basicConfig, getLogger, DEBUG, INFO
Felix Dehon's avatar
Felix Dehon committed
basicConfig(filename="output.log", filemode="w+", level=DEBUG)
Felix Dehon's avatar
Felix Dehon committed

logger = getLogger()
logger.setLevel(DEBUG)

from PyQt5.QtWidgets import QApplication, QPushButton, QDialog
from PyQt5.QtCore import Qt
from PyQt5 import uic
Lorenz Wührl's avatar
Lorenz Wührl committed

from UserInterface.ui import MainWindow
Felix Dehon's avatar
Felix Dehon committed
from MotorController.motorcontroller import Axis
Felix Dehon's avatar
Felix Dehon committed
import constants

Felix Dehon's avatar
Felix Dehon committed

Felix Dehon's avatar
Felix Dehon committed
def read_config():
    with open("config.txt", "r") as config_file:
        config = {} 
        for line in config_file.readlines():
            if line.startswith("#") or "=" not in line:
                continue
            
            prop, value = line.split("=", 1)
            prop, value = prop.rstrip().lstrip(), value.rstrip().lstrip()
            if not prop or not value: continue
            
            config[prop] = value
    return config

def write_config(params):
    if not "version" in params:
        params["version"] = "1.0.0"
    
    params["helicon-path"] = constants.HELICON_PATH
Felix Dehon's avatar
Felix Dehon committed
    # params["base-directory"] = constants.DEFAULT_BASE_DIR
Felix Dehon's avatar
Felix Dehon committed
    params["image-extension"] = constants.IMG_EXTENSION
    params["stack-speed"] = constants.STACK_SPEED
    params["number-of-stacks"] = constants.DEFAULT_NUM_OF_STACKS
    params["stack-step-size"] = constants.DEFAULT_STACK_STEP_SIZE
    
    with open("config.txt", "w") as config_file:
        for key, val in params.items() :
            config_file.write(f"{key}={val}\n")

def save_config(cfg):
    try:
        constants.__setattr__("IMG_EXTENSION", cfg["image-extension"]) if "image-extension" in cfg else None
        helicon_path = cfg["helicon-path"] if "helicon-path" in cfg else "undefined"
        constants.__setattr__("HELICON_PATH", None if helicon_path.lower() == "none" else helicon_path)
        constants.__setattr__("STACK_SPEED", int(cfg["stack-speed"])) if "stack-speed" in cfg else None
        constants.__setattr__("DEFAULT_NUM_OF_STACKS", int(cfg["number-of-stacks"])) if "number-of-stacks" in cfg else None
        constants.__setattr__("DEFAULT_STACK_STEP_SIZE", float(cfg["stack-step-size"])) if "stack-step-size" in cfg else None
        constants.__setattr__("DEFAULT_BASE_DIR", cfg["base-directory"]) if "base-directory" in cfg else None
Felix Dehon's avatar
Felix Dehon committed
    except:
        # parameter is missing or ValueError, this invalid data can be ignored
        pass

def check_version(ver):
    """Compares this version to the version in the online gitlab repository"""
    pass
Lorenz Wührl's avatar
Lorenz Wührl committed

def find_arduino() -> Serial:
Felix Dehon's avatar
Felix Dehon committed
    list_of_ports = list(comports())
    logger.debug(list(map(str, list_of_ports)))
Felix Dehon's avatar
Felix Dehon committed
    if not list_of_ports:
        return None
    
    if "Arduino" in str(list(map(str, list_of_ports))):
        for port, desc, hwid in list_of_ports:
Felix Dehon's avatar
Felix Dehon committed
            
            if "Arduino" in desc:
                logger.debug(f"found arduino: {port}")
                return Serial(port, baudrate=115200, timeout=.05)
Felix Dehon's avatar
Felix Dehon committed
    for port, desc, hwid in list_of_ports:
        logger.debug(f"{port=}, {desc=}, {hwid=}") 
        try:
            con = Serial(port, baudrate=115200, timeout=.05)
            sleep(2)
            logger.debug(f"written to {port}")
            t0=time()
Felix Dehon's avatar
Felix Dehon committed
            con.write(b"arduino")
            while time()- t0 < .1:
                ans = con.readline()
                logger.debug(f"answer: {ans}")
                
                if ans.decode("ascii").strip() == "yes":
                    logger.debug(f"{port} won")
                    return con
                
            con.close()
Felix Dehon's avatar
Felix Dehon committed
        except Exception as e:
            logger.debug(f"error while trying to connect to a COM port: {e}")
    
    return None


class StartWindow(QDialog):
    def __init__(self):
        super().__init__()
        uic.loadUi("UserInterface/logo_screen.ui", self)
        self.setWindowFlag(Qt.WindowType.FramelessWindowHint)


class NoConnectionWindow(QDialog):
    def __init__(self):
        super().__init__()
        uic.loadUi("UserInterface/connection_error.ui", self)
        self.retry_bttn = self.findChild(QPushButton, "retry_bttn")
        self.close_bttn = self.findChild(QPushButton, "close_bttn")
        self.retry_bttn.clicked.connect(self.close)
        self.close_bttn.clicked.connect(exit)


Lorenz Wührl's avatar
Lorenz Wührl committed

if __name__ == "__main__":
Felix Dehon's avatar
Felix Dehon committed
    cfg = read_config()
    if "version" in cfg:
        check_version(cfg["version"])
    save_config(cfg)
    
Lorenz Wührl's avatar
Lorenz Wührl committed
    app = QApplication(sys.argv)
    
    start_window = StartWindow()
    start_window.show()
    
    arduino = find_arduino()
    connection_window = None
    
    while arduino is None:
        connection_window = NoConnectionWindow()
        connection_window.exec()
        arduino = find_arduino()
    
    if connection_window:
        connection_window.close()
    start_window.close()
    
    axis = Axis(arduino)
Lorenz Wührl's avatar
Lorenz Wührl committed
    window = MainWindow(axis)
    window.show()
Felix Dehon's avatar
Felix Dehon committed
    rtn = app.exec()
Felix Dehon's avatar
Felix Dehon committed
    logger.info("app executed")
Felix Dehon's avatar
Felix Dehon committed
    write_config(cfg)
    
Felix Dehon's avatar
Felix Dehon committed
    logger.info("app done")
Felix Dehon's avatar
Felix Dehon committed
    sys.exit(rtn)