diff --git a/docker-compose.yml b/docker-compose.yml
index d68544d643355c49b148a7b36cc8dc93ea6da7ec..8f0fc583c6acfada4dcd6fd706cee9225d87d5ac 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -41,7 +41,7 @@ services:
     image: eclipse-mosquitto
     ports:
       - '0.0.0.0:1883:1883'
-      - '0.0.0.0:9001:9001'
+      - '0.0.0.0:443:443'
     volumes:
       - ./mosquitto/config/mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
     restart: always
diff --git a/mosquitto/config/mosquitto.conf b/mosquitto/config/mosquitto.conf
index f2c19455bb5803a740551be9205af05f2bbda726..bb96d2beea665d546664decc6eedd9c17053888c 100644
--- a/mosquitto/config/mosquitto.conf
+++ b/mosquitto/config/mosquitto.conf
@@ -1,6 +1,6 @@
 allow_anonymous true
 listener 1883
-listener 9001
+listener 443
 protocol websockets
 persistence true
 persistence_location /mosquitto/data/
\ No newline at end of file
diff --git a/serial_to_mqtt_bridge/Dockerfile b/serial_to_mqtt_bridge/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..fc7eb347a86933d25e74e83997bcfdb5e5d1262d
--- /dev/null
+++ b/serial_to_mqtt_bridge/Dockerfile
@@ -0,0 +1,8 @@
+FROM python:3.9 
+# Or any preferred Python version.
+WORKDIR /src
+COPY serial_to_mqtt.py /src/serial_to_mqtt.py
+COPY requirements.txt /src/requirements.txt
+RUN pip install -r requirements.txt
+CMD ["python3", "-u", "/src/serial_to_mqtt.py", "--serial_port", "sim", "--mqtt_broker", "ws://mosquitto", "--mqtt_port", "443"] 
+# Or enter the name of your unique directory and parameter set.
diff --git a/serial_to_mqtt_bridge/_version.py b/serial_to_mqtt_bridge/_version.py
new file mode 100644
index 0000000000000000000000000000000000000000..2bf0baf1d49242665e61b0ee63bdbf5f2354e901
--- /dev/null
+++ b/serial_to_mqtt_bridge/_version.py
@@ -0,0 +1,2 @@
+# placeholder will be overwritten by PyInstaller
+version = ""
\ No newline at end of file
diff --git a/serial_to_mqtt_bridge/config.yaml b/serial_to_mqtt_bridge/config.yaml
index e4edc643944d487e82095bc1980e10734649b3c5..a04955e2295e7526f0c2be03d9fc3b985491e77f 100644
--- a/serial_to_mqtt_bridge/config.yaml
+++ b/serial_to_mqtt_bridge/config.yaml
@@ -1,8 +1,7 @@
 mqtt:
-  broker: "localhost"
-  port: 1883
+  broker: "rocket.mwave.eti.pg.gda.pl"
+  port: 443
   topic: "serial2MQTT"
-
 serial:
   baud_rate: 115200
 
diff --git a/serial_to_mqtt_bridge/create_exe.bat b/serial_to_mqtt_bridge/create_exe.bat
index 105ee7ffd842b374ee99e78f18523ba8c518bb1e..172b9d4439e16f7ee996acf2bfc3da2cc5035412 100644
--- a/serial_to_mqtt_bridge/create_exe.bat
+++ b/serial_to_mqtt_bridge/create_exe.bat
@@ -19,36 +19,47 @@ if errorlevel 1 (
     pip install pyinstaller
 )
 
-:: Check if required packages are installed
-pip show paho-mqtt >nul 2>&1
-if errorlevel 1 (
-    echo Installing required packages...
-    pip install -r requirements.txt
-)
+:: Install all required packages
+echo Installing required packages...
+pip install -r requirements.txt
+
+:: Get git SHA
+for /f %%i in ('git rev-parse --short HEAD') do set GIT_SHA=%%i
+echo Building version: %GIT_SHA%
 
-:: Generate spec files
-echo Generating spec files...
-python -m PyInstaller --onefile --name serial_to_mqtt serial_to_mqtt.py
-python -m PyInstaller --onefile --name serial_to_mqtt_sim serial_to_mqtt_sim.py
+:: Update _version.py with git SHA
+echo Updating _version.py with git SHA...
+python -c "with open('_version.py', 'w') as f: f.write('version = \"%GIT_SHA%\"')"
 
-:: Compile programs
-echo Compiling programs...
+:: Generate spec file
+echo Generating spec file...
+if not exist favicon.ico (
+    echo Warning: serial_to_mqtt.ico not found. Creating spec without custom icon.
+    python -m PyInstaller --name serial_to_mqtt --onefile --windowed serial_to_mqtt.py
+) else (
+    echo Using serial_to_mqtt.ico as application icon...
+    python -m PyInstaller --name serial_to_mqtt --onefile --windowed --icon=favicon.ico serial_to_mqtt.py
+)
+
+:: Compile program
+echo Compiling program...
+set PYTHONPATH=%PYTHONPATH%;%CD%
 python -m PyInstaller serial_to_mqtt.spec
-python -m PyInstaller serial_to_mqtt_sim.spec
 
-:: Move exe files to main directory
-echo Moving exe files to main directory...
-move /Y dist\serial_to_mqtt.exe .\serial_to_mqtt.exe
-move /Y dist\serial_to_mqtt_sim.exe .\serial_to_mqtt_sim.exe
+:: Move exe file to main directory
+echo Moving exe file to main directory...
+move /Y dist\serial_to_mqtt.exe .\susGatewayApp.exe
 
 :: Clean temporary folders
 echo Cleaning temporary folders...
 rmdir /S /Q build
 rmdir /S /Q dist
 del /F /Q serial_to_mqtt.spec
-del /F /Q serial_to_mqtt_sim.spec
 
-echo Binaries created successfully:
-echo - serial_to_mqtt.exe
-echo - serial_to_mqtt_sim.exe
-pause 
\ No newline at end of file
+:: Restore default version in _version.py
+echo Restoring default version in _version.py...
+python -c "with open('_version.py', 'w') as f: f.write('# placeholder will be overwritten by PyInstaller\nversion = \"\"')"
+
+echo Binary created successfully:
+echo - serial_to_mqtt.exe (version: %GIT_SHA%)
+pause  
\ No newline at end of file
diff --git a/serial_to_mqtt_bridge/favicon.ico b/serial_to_mqtt_bridge/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..7b4d580e3ef757a9c8ae67ccd2e3064d934bb90a
Binary files /dev/null and b/serial_to_mqtt_bridge/favicon.ico differ
diff --git a/serial_to_mqtt_bridge/requirements.txt b/serial_to_mqtt_bridge/requirements.txt
index 808abc055cda42e56c1f4fa0d51f4c263f101294..0c05005dfe94a54783eb0853168a2f154a15b010 100644
--- a/serial_to_mqtt_bridge/requirements.txt
+++ b/serial_to_mqtt_bridge/requirements.txt
@@ -1,4 +1,4 @@
-paho-mqtt
-pyserial
-argparse
-PyYAML
\ No newline at end of file
+paho-mqtt==1.6.1
+pyyaml==6.0.1
+pyserial==3.5
+pywin32==306
\ No newline at end of file
diff --git a/serial_to_mqtt_bridge/serial_to_mqtt.py b/serial_to_mqtt_bridge/serial_to_mqtt.py
index 06a7e4f62a957c32f44c2e1c9a07b78c85d931dc..7a839c269683dcc52c91a8d473d802ed9b82d22a 100755
--- a/serial_to_mqtt_bridge/serial_to_mqtt.py
+++ b/serial_to_mqtt_bridge/serial_to_mqtt.py
@@ -6,6 +6,14 @@ import argparse
 import yaml
 import os
 import serial.tools.list_ports
+import ssl
+import random
+import tkinter as tk
+from tkinter import ttk, messagebox, scrolledtext
+import threading
+import queue
+import subprocess
+import sys
 
 def list_serial_ports():
     """
@@ -29,6 +37,15 @@ def list_serial_ports():
         print("-" * 50)
         port_list.append(port.device)
     
+    # Add simulation option at the end
+    sim_index = len(ports) + 1
+    print(f"{sim_index}. Port: sim")
+    print("   Description: Simulation mode")
+    print("   Manufacturer: Internal")
+    print("   Hardware ID: N/A")
+    print("-" * 50)
+    port_list.append("sim")
+    
     return port_list
 
 def select_serial_port():
@@ -79,93 +96,404 @@ def load_config(file_path="config.yaml"):
         return {}
 
 # MQTT connection initialization
-client = mqtt.Client()
-
-def connect_mqtt(broker, port):
-    client.connect(broker, port, 60)
-    client.loop_start()
+def create_mqtt_client(broker_url):
+    """
+    Creates MQTT client with appropriate transport based on broker URL prefix
+    """
+    if broker_url.startswith('mqtt://'):
+        print("Using MQTT protocol...")
+        return mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
+    elif broker_url.startswith('ws://'):
+        print("Using WebSocket protocol without TLS...")
+        return mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, transport="websockets")
+    elif broker_url.startswith('wss://'):
+        print("Using WebSocket protocol with TLS...")
+        return mqtt.Client(mqtt.CallbackAPIVersion.VERSION1, transport="websockets")
+    else:
+        print("No protocol prefix found, using MQTT protocol...")
+        return mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
 
-# Function to read lines from file cyclically
-def cyclic_file_reader(file_path):
-    while True:
-        with open(file_path, 'r') as file:
-            for line in file:
-                yield line.strip()  # Yield each line, stripped of whitespace
+def connect_mqtt(broker, port, username=None, password=None):
+    """
+    Connect to MQTT broker with optional authentication and TLS
+    """
+    try:
+        print(f"Attempting to connect to MQTT broker {broker}:{port}...")
+        
+        # Create client with appropriate transport
+        global client
+        client = create_mqtt_client(broker)
+        
+        # Configure WebSocket if needed
+        if broker.startswith(('ws://', 'wss://')):
+            client.ws_set_options(path="/ws")
+        
+        # Configure TLS if using wss://
+        if broker.startswith('wss://'):
+            print("Using TLS for secure connection...")
+            client.tls_set(tls_version=ssl.PROTOCOL_TLSv1_2)
+            client.tls_insecure_set(True)
+        else:
+            print("Using unencrypted connection...")
+        
+        # Authentication configuration only if username and password are provided
+        if username and password and username.strip() and password.strip():
+            print("Using MQTT authentication...")
+            client.username_pw_set(username, password)
+        else:
+            print("Connecting without MQTT authentication...")
+        
+        # Enable logging
+        client.enable_logger()
+        
+        # Remove protocol prefix from broker address if present
+        broker_address = broker.split('://')[-1]
+        
+        # Connect with error handling
+        try:
+            client.connect(broker_address, port, 60)
+            client.loop_start()
+            print("Successfully connected to MQTT broker")
+        except Exception as e:
+            print(f"Failed to connect to MQTT broker: {str(e)}")
+            raise
+            
+    except Exception as e:
+        print(f"Error setting up MQTT client: {str(e)}")
+        raise
 
-# Main function to handle serial data or send lines from file if no port is provided
-def main(serial_port=None, baud_rate=115200, file_path="sim_data.txt", mqtt_broker="192.168.52.5", mqtt_port=1883, mqtt_topic="serial2MQTT", sim_interval=1):
-    connect_mqtt(mqtt_broker, mqtt_port)
+def generate_sim_data():
+    """
+    Generates random simulation data similar to create_sim_data.py
+    """
+    # Define the valid range for `char`
+    valid_chars = list(range(13, 25)) + [37, 38]  # From 13 to 24 and 37, 38
     
-    if serial_port.lower() != "sim":
-        # If serial port is provided, read from it
-        ser = serial.Serial(serial_port, baud_rate, timeout=1)
-        try:
+    # Generate random values for fields
+    rssi = random.randint(45, 92)  # RSSI value between -92 and -45
+    char = random.choice(valid_chars)  # Randomly choose from valid char values
+    channel = random.randint(37, 39)  # Channel value between 37 and 39
+    tx_power = 8  # Fixed tx_power value
+    temp = int(random.randint(0, 4095))  # Temperature value between 0 and 1800
+    pH = int(random.randint(0, 4095))  # pH value between 0 and 1800
+    pHRaw = int(pH/8)  # pH value between 0 and 1800
+    battery = int(random.randint(0, 4095))  # pH value between 0 and 1800
+    
+    # Format the line according to the InfluxDB requirements
+    return (f"dongle_t=c000d0009,beacon_t=c000beac0004 "
+            f"rssi={rssi},char={char},channel={channel},tx_power={tx_power},"
+            f"temp={temp},pH={pH},pHRaw={pHRaw},battery={battery},timestamp=")
+
+def cyclic_data_generator(file_path):
+    """
+    Generator that either reads data from file cyclically or generates random data
+    """
+    try:
+        if os.path.exists(file_path):
+            print(f"Reading simulation data from file: {file_path}")
             while True:
-                # Read data from the serial port
-                if ser.in_waiting > 0:
-                    line = ser.readline().decode('utf-8').strip()
-                    print(f"Received from serial port: {line}")
-                    print(f"Sent to MQTT broker={mqtt_broker} in topic={mqtt_topic} msg={line}")
-                    # Send data to MQTT
-                    client.publish(mqtt_topic, line)                    
-                time.sleep(0.1)  # Short delay
-                
-        except KeyboardInterrupt:
-            print("Program terminated.")
-        finally:
-            # Close serial connection
-            ser.close()
-            client.loop_stop()
-            client.disconnect()
-    else:
-        # If simulation mode is selected, send lines from the file cyclically
-        file_reader = cyclic_file_reader(file_path)
-        cnt=0
-        try:
+                with open(file_path, 'r') as file:
+                    for line in file:
+                        line = line.strip()
+                        if line:  # Skip empty lines
+                            yield line
+        else:
+            print(f"Warning: File '{file_path}' not found. Generating random simulation data...")
             while True:
-                # Get the next line from the file
-                line = next(file_reader)
-                cnt = cnt +1
-                msg=mqtt_topic+","+line+str(cnt)
-                client.publish(msg)
-                print(f"Sent to MQTT broker={mqtt_broker} in topic={mqtt_topic} msg={msg}")
-                time.sleep(sim_interval)  # Use interval from YAML config
+                yield generate_sim_data()
+    except Exception as e:
+        print(f"Error in data generator: {str(e)}")
+        raise
+
+def get_version():
+    """Get the version from the executable file info"""
+    try:
+        if getattr(sys, 'frozen', False):
+            # Jeśli jesteśmy w skompilowanym exe
+            from _version import version
+            return version
+        else:
+            # W trybie deweloperskim
+            return "dev"
+    except Exception as e:
+        # Zwracamy błąd razem z wersją
+        return f"N/A (Error: {str(e)})"
+
+class SerialToMQTTGUI:
+    def __init__(self, root):
+        self.root = root
+        self.root.title("Serial to MQTT Bridge")
+        self.root.geometry("800x600")
+        
+        # Variables
+        self.is_running = False
+        self.serial_port = None
+        self.mqtt_client = None
+        self.data_queue = queue.Queue()
+        
+        # Load configuration
+        self.config = load_config()
+        
+        self.create_widgets()
+        self.setup_layout()
+        
+    def create_widgets(self):
+        # Serial Port Frame
+        self.serial_frame = ttk.LabelFrame(self.root, text="Serial Port Settings", padding="5")
+        
+        self.port_var = tk.StringVar()
+        self.port_combo = ttk.Combobox(self.serial_frame, textvariable=self.port_var)
+        self.refresh_ports()
+        
+        self.refresh_btn = ttk.Button(self.serial_frame, text="Refresh Ports", command=self.refresh_ports)
+        self.baud_var = tk.StringVar(value=str(self.config.get('serial', {}).get('baud_rate', 115200)))
+        self.baud_label = ttk.Label(self.serial_frame, text="Baud Rate:")
+        self.baud_entry = ttk.Entry(self.serial_frame, textvariable=self.baud_var, width=10)
+        
+        # MQTT Settings Frame
+        self.mqtt_frame = ttk.LabelFrame(self.root, text="MQTT Settings", padding="5")
+        
+        self.broker_var = tk.StringVar(value=self.config.get('mqtt', {}).get('broker', "wss://rocket.mwave.eti.pg.gda.pl"))
+        self.broker_label = ttk.Label(self.mqtt_frame, text="Broker:")
+        self.broker_entry = ttk.Entry(self.mqtt_frame, textvariable=self.broker_var, width=40)
+        
+        self.port_mqtt_var = tk.StringVar(value=str(self.config.get('mqtt', {}).get('port', 443)))
+        self.port_mqtt_label = ttk.Label(self.mqtt_frame, text="Port:")
+        self.port_mqtt_entry = ttk.Entry(self.mqtt_frame, textvariable=self.port_mqtt_var, width=10)
+        
+        self.topic_var = tk.StringVar(value=self.config.get('mqtt', {}).get('topic', "serial2MQTT"))
+        self.topic_label = ttk.Label(self.mqtt_frame, text="Topic:")
+        self.topic_entry = ttk.Entry(self.mqtt_frame, textvariable=self.topic_var, width=40)
+        
+        self.username_var = tk.StringVar(value=self.config.get('mqtt', {}).get('username', ""))
+        self.username_label = ttk.Label(self.mqtt_frame, text="Username:")
+        self.username_entry = ttk.Entry(self.mqtt_frame, textvariable=self.username_var, width=20)
+        
+        self.password_var = tk.StringVar(value=self.config.get('mqtt', {}).get('password', ""))
+        self.password_label = ttk.Label(self.mqtt_frame, text="Password:")
+        self.password_entry = ttk.Entry(self.mqtt_frame, textvariable=self.password_var, show="*", width=20)
+        
+        # Simulation Settings Frame
+        self.sim_frame = ttk.LabelFrame(self.root, text="Simulation Settings", padding="5")
+        
+        self.sim_interval_var = tk.StringVar(value=str(self.config.get('sim', {}).get('interval', 1)))
+        self.sim_interval_label = ttk.Label(self.sim_frame, text="Interval (s):")
+        self.sim_interval_entry = ttk.Entry(self.sim_frame, textvariable=self.sim_interval_var, width=10)
+        
+        self.file_path_var = tk.StringVar(value=self.config.get('sim', {}).get('file_path', "sim_data.txt"))
+        self.file_path_label = ttk.Label(self.sim_frame, text="Data File:")
+        self.file_path_entry = ttk.Entry(self.sim_frame, textvariable=self.file_path_var, width=40)
+        
+        # Control Buttons
+        self.control_frame = ttk.Frame(self.root)
+        self.start_btn = ttk.Button(self.control_frame, text="Start", command=self.start)
+        self.stop_btn = ttk.Button(self.control_frame, text="Stop", command=self.stop, state="disabled")
+        
+        # Log Display
+        self.log_frame = ttk.LabelFrame(self.root, text="Log", padding="5")
+        self.log_text = scrolledtext.ScrolledText(self.log_frame, height=15)
+        
+        # Dashboard Link
+        self.dashboard_frame = ttk.Frame(self.root)
+        self.dashboard_label = ttk.Label(self.dashboard_frame, text="View data in Grafana dashboard:")
+        self.dashboard_link = ttk.Label(self.dashboard_frame, text="https://sustronics.mwave.eti.pg.gda.pl/d/1Mar-DTiz/sustronicspilot3-3", foreground="blue", cursor="hand2")
+        self.dashboard_link.bind("<Button-1>", lambda e: self.open_dashboard())
+        self.dashboard_link.bind("<Enter>", lambda e: self.dashboard_link.configure(underline=True))
+        self.dashboard_link.bind("<Leave>", lambda e: self.dashboard_link.configure(underline=False))
+        
+        # Git Info Frame
+        self.git_frame = ttk.Frame(self.root)
+        git_sha = get_version()
+        self.git_label = ttk.Label(self.git_frame, text=f"Version: {git_sha}", foreground="gray")
+        # Jeśli wystąpił błąd, logujemy go
+        if "Error:" in git_sha:
+            self.log(git_sha)
+        
+    def setup_layout(self):
+        # Serial Port Frame
+        self.serial_frame.grid(row=0, column=0, padx=5, pady=5, sticky="ew")
+        self.port_combo.grid(row=0, column=0, padx=5, pady=5)
+        self.refresh_btn.grid(row=0, column=1, padx=5, pady=5)
+        self.baud_label.grid(row=0, column=2, padx=5, pady=5)
+        self.baud_entry.grid(row=0, column=3, padx=5, pady=5)
+        
+        # MQTT Settings Frame
+        self.mqtt_frame.grid(row=1, column=0, padx=5, pady=5, sticky="ew")
+        self.broker_label.grid(row=0, column=0, padx=5, pady=5)
+        self.broker_entry.grid(row=0, column=1, columnspan=2, padx=5, pady=5)
+        self.port_mqtt_label.grid(row=0, column=3, padx=5, pady=5)
+        self.port_mqtt_entry.grid(row=0, column=4, padx=5, pady=5)
+        
+        self.topic_label.grid(row=1, column=0, padx=5, pady=5)
+        self.topic_entry.grid(row=1, column=1, columnspan=2, padx=5, pady=5)
+        
+        self.username_label.grid(row=2, column=0, padx=5, pady=5)
+        self.username_entry.grid(row=2, column=1, padx=5, pady=5)
+        self.password_label.grid(row=2, column=2, padx=5, pady=5)
+        self.password_entry.grid(row=2, column=3, padx=5, pady=5)
+        
+        # Simulation Settings Frame
+        self.sim_frame.grid(row=2, column=0, padx=5, pady=5, sticky="ew")
+        self.sim_interval_label.grid(row=0, column=0, padx=5, pady=5)
+        self.sim_interval_entry.grid(row=0, column=1, padx=5, pady=5)
+        self.file_path_label.grid(row=0, column=2, padx=5, pady=5)
+        self.file_path_entry.grid(row=0, column=3, columnspan=2, padx=5, pady=5)
+        
+        # Control Buttons
+        self.control_frame.grid(row=3, column=0, padx=5, pady=5)
+        self.start_btn.grid(row=0, column=0, padx=5)
+        self.stop_btn.grid(row=0, column=1, padx=5)
+        
+        # Dashboard Link
+        self.dashboard_frame.grid(row=4, column=0, padx=5, pady=5)
+        self.dashboard_label.grid(row=0, column=0, padx=5)
+        self.dashboard_link.grid(row=0, column=1, padx=5)
+        
+        # Git Info
+        self.git_frame.grid(row=5, column=0, padx=5, pady=5)
+        self.git_label.grid(row=0, column=0, padx=5)
+        
+        # Log Display
+        self.log_frame.grid(row=6, column=0, padx=5, pady=5, sticky="nsew")
+        self.log_text.grid(row=0, column=0, padx=5, pady=5, sticky="nsew")
+        
+        # Configure grid weights
+        self.root.grid_rowconfigure(6, weight=1)
+        self.root.grid_columnconfigure(0, weight=1)
+        
+    def refresh_ports(self):
+        ports = list_serial_ports()
+        if ports:
+            self.port_combo['values'] = ports
+            if not self.port_var.get():
+                self.port_combo.set(ports[0])
+        else:
+            self.port_combo['values'] = ['sim']
+            self.port_combo.set('sim')
+            
+    def log(self, message):
+        self.log_text.insert(tk.END, f"{message}\n")
+        self.log_text.see(tk.END)
+        
+    def start(self):
+        try:
+            # Get values from GUI
+            port = self.port_var.get()
+            baud_rate = int(self.baud_var.get())
+            broker = self.broker_var.get()
+            mqtt_port = int(self.port_mqtt_var.get())
+            topic = self.topic_var.get()
+            username = self.username_var.get()
+            password = self.password_var.get()
+            sim_interval = int(self.sim_interval_var.get())
+            file_path = self.file_path_var.get()
+            
+            # Connect to MQTT
+            connect_mqtt(broker, mqtt_port, username, password)
+            
+            # Start the main thread
+            self.is_running = True
+            self.start_btn.config(state="disabled")
+            self.stop_btn.config(state="normal")
+            
+            # Start the main processing thread
+            self.main_thread = threading.Thread(
+                target=self.main_loop,
+                args=(port, baud_rate, file_path, broker, mqtt_port, topic, sim_interval, username, password)
+            )
+            self.main_thread.daemon = True
+            self.main_thread.start()
+            
+            self.log("Started successfully")
+            
+        except Exception as e:
+            messagebox.showerror("Error", f"Failed to start: {str(e)}")
+            self.stop()
+            
+    def stop(self):
+        self.is_running = False
+        self.start_btn.config(state="normal")
+        self.stop_btn.config(state="disabled")
+        
+        if self.serial_port:
+            try:
+                self.serial_port.close()
+            except:
+                pass
                 
-        except KeyboardInterrupt:
-            print("Program terminated.")
+        if self.mqtt_client:
+            try:
+                self.mqtt_client.loop_stop()
+                self.mqtt_client.disconnect()
+            except:
+                pass
+                
+        self.log("Stopped")
+        
+    def main_loop(self, serial_port, baud_rate, file_path, mqtt_broker, mqtt_port, mqtt_topic, sim_interval, mqtt_username, mqtt_password):
+        """
+        Main processing loop for both serial and simulation modes
+        """
+        try:
+            if serial_port.lower() != "sim":
+                # Serial port mode
+                try:
+                    self.serial_port = serial.Serial(serial_port, baud_rate, timeout=1)
+                    self.log(f"Connected to serial port: {serial_port}")
+                    
+                    while self.is_running:
+                        if self.serial_port.in_waiting > 0:
+                            try:
+                                line = self.serial_port.readline().decode('utf-8').strip()
+                                if line:  # Skip empty lines
+                                    self.log(f"Received from serial port: {line}")
+                                    client.publish(mqtt_topic, line)
+                                    self.log(f"Sent to MQTT broker={mqtt_broker} in topic={mqtt_topic}, msg={line}")
+                            except Exception as e:
+                                self.log(f"Error processing serial data: {str(e)}")
+                        time.sleep(0.1)
+                        
+                except Exception as e:
+                    self.log(f"Error in serial port connection: {str(e)}")
+                finally:
+                    if self.serial_port:
+                        self.serial_port.close()
+                        self.log("Serial port closed")
+            else:
+                # Simulation mode
+                try:
+                    data_generator = cyclic_data_generator(file_path)
+                    cnt = 0
+                    self.log("Started simulation mode")
+                    
+                    while self.is_running:
+                        try:
+                            line = next(data_generator)
+                            cnt += 1
+                            msg = f"{mqtt_topic},{line}{cnt}"
+                            client.publish(mqtt_topic, msg)
+                            self.log(f"Sent to MQTT broker={mqtt_broker} in topic={mqtt_topic}, msg={msg}")
+                            time.sleep(sim_interval)
+                        except Exception as e:
+                            self.log(f"Error generating simulation data: {str(e)}")
+                            break
+                            
+                except Exception as e:
+                    self.log(f"Error in simulation setup: {str(e)}")
+                    
+        except Exception as e:
+            self.log(f"Critical error in main loop: {str(e)}")
         finally:
-            client.loop_stop()
-            client.disconnect()
+            self.stop()
+
+    def open_dashboard(self):
+        import webbrowser
+        webbrowser.open("https://sustronics.mwave.eti.pg.gda.pl/d/1Mar-DTiz/sustronicspilot3-3?orgId=2&refresh=1m")
+
+def main():
+    root = tk.Tk()
+    app = SerialToMQTTGUI(root)
+    root.mainloop()
 
 if __name__ == "__main__":
-    # Load configuration from YAML
-    config = load_config()
-    
-    # Argument parser for serial port, baud rate, and file path
-    parser = argparse.ArgumentParser(description="Read data from serial port and publish to MQTT.")
-    parser.add_argument("--serial_port", type=str, help="Serial port to connect to (e.g., COM3) or 'sim' for simulation mode")
-    parser.add_argument("--baud_rate", type=int, default=config.get('serial', {}).get('baud_rate', 115200), help="Baud rate for serial communication")
-    parser.add_argument("--file_path", type=str, default=config.get('sim', {}).get('file_path', "sim_data.txt"), help="Path to the file with data for MQTT")
-    parser.add_argument("--mqtt_broker", type=str, default=config.get('mqtt', {}).get('broker', "192.168.52.5"), help="MQTT broker address")
-    parser.add_argument("--mqtt_port", type=int, default=config.get('mqtt', {}).get('port', 1883), help="MQTT port")
-    parser.add_argument("--mqtt_topic", type=str, default=config.get('mqtt', {}).get('topic', "serial2MQTT"), help="MQTT topic to publish data")
-    parser.add_argument("--sim_interval", type=int, default=config.get('sim', {}).get('interval', 1), help="Interval in seconds for sending data from file")
-    args = parser.parse_args()
-    
-    # If port is not provided as argument, let user select it
-    if not args.serial_port:
-        args.serial_port = select_serial_port()
-        if not args.serial_port:
-            print("No port selected. Program will terminate.")
-            exit(1)
-    
-    # Run main with configuration from YAML and/or command line arguments
-    main(
-        serial_port=args.serial_port,
-        baud_rate=args.baud_rate,
-        file_path=args.file_path,
-        mqtt_broker=args.mqtt_broker,
-        mqtt_port=args.mqtt_port,
-        mqtt_topic=args.mqtt_topic,
-        sim_interval=args.sim_interval
-    )
+    main()
diff --git a/serial_to_mqtt_bridge/serial_to_mqtt_sim.exe b/serial_to_mqtt_bridge/serial_to_mqtt_sim.exe
deleted file mode 100644
index e81340b199bdac3804277e7ea656f1666929fe07..0000000000000000000000000000000000000000
Binary files a/serial_to_mqtt_bridge/serial_to_mqtt_sim.exe and /dev/null differ
diff --git a/serial_to_mqtt_bridge/serial_to_mqtt_sim.py b/serial_to_mqtt_bridge/serial_to_mqtt_sim.py
deleted file mode 100755
index 8ed50b4ded3bd6f7f916d0a9e2eba8e99e595817..0000000000000000000000000000000000000000
--- a/serial_to_mqtt_bridge/serial_to_mqtt_sim.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python
-import paho.mqtt.client as mqtt
-import time
-import argparse
-import yaml
-import os
-import random
-
-# Built-in simulation data
-SIM_DATA = [
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=49,char=22,channel=37,tx_power=8,temp=928,pH=372,pHRaw=46,battery=3002,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=22,channel=39,tx_power=8,temp=3914,pH=3391,pHRaw=423,battery=2158,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=60,char=38,channel=37,tx_power=8,temp=1645,pH=600,pHRaw=75,battery=512,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=69,char=21,channel=39,tx_power=8,temp=833,pH=1331,pHRaw=166,battery=259,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=51,char=20,channel=37,tx_power=8,temp=1574,pH=2811,pHRaw=351,battery=405,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=85,char=24,channel=39,tx_power=8,temp=1390,pH=914,pHRaw=114,battery=523,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=50,char=22,channel=39,tx_power=8,temp=667,pH=2074,pHRaw=259,battery=2569,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=48,char=24,channel=37,tx_power=8,temp=4090,pH=1586,pHRaw=198,battery=3991,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=46,char=20,channel=39,tx_power=8,temp=2689,pH=1329,pHRaw=166,battery=479,timestamp=",
-    "dongle_t=c000d0009,beacon_t=c000beac0004 rssi=76,char=22,channel=38,tx_power=8,temp=2734,pH=3961,pHRaw=495,battery=3025,timestamp="
-]
-
-def generate_sim_data():
-    """
-    Generates random simulation data in the same format as the original data
-    """
-    valid_chars = list(range(13, 25)) + [37, 38]
-    rssi = random.randint(45, 92)
-    char = random.choice(valid_chars)
-    channel = random.randint(37, 39)
-    tx_power = 8
-    temp = random.randint(0, 4095)
-    pH = random.randint(0, 4095)
-    pHRaw = int(pH/8)
-    battery = random.randint(0, 4095)
-    
-    return (f"dongle_t=c000d0009,beacon_t=c000beac0004 "
-            f"rssi={rssi},char={char},channel={channel},tx_power={tx_power},"
-            f"temp={temp},pH={pH},pHRaw={pHRaw},battery={battery},timestamp=")
-
-# Load default configuration from YAML file
-def load_config(file_path="config.yaml"):
-    """
-    Load configuration from YAML file.
-    If file doesn't exist or there's an error, return empty dict.
-    Default values are handled in argument parser.
-    """
-    if not os.path.exists(file_path):
-        print(f"Warning: Configuration file '{file_path}' not found. Using default values from command line arguments.")
-        return {}
-        
-    try:
-        with open(file_path, 'r') as file:
-            return yaml.safe_load(file) or {}
-    except Exception as e:
-        print(f"Warning: Error reading configuration file '{file_path}': {str(e)}. Using default values from command line arguments.")
-        return {}
-
-# MQTT connection initialization
-client = mqtt.Client()
-
-def connect_mqtt(broker, port):
-    client.connect(broker, port, 60)
-    client.loop_start()
-
-def cyclic_data_generator():
-    """
-    Generator that yields data from SIM_DATA cyclically
-    """
-    while True:
-        for data in SIM_DATA:
-            yield data
-
-def random_data_generator():
-    """
-    Generator that yields random simulation data
-    """
-    while True:
-        yield generate_sim_data()
-
-# Main function to handle simulation data
-def main(use_random_data=False, mqtt_broker="localhost", mqtt_port=1883, mqtt_topic="serial2MQTT", sim_interval=1):
-    connect_mqtt(mqtt_broker, mqtt_port)
-    
-    # Choose data generator based on mode
-    data_generator = random_data_generator() if use_random_data else cyclic_data_generator()
-    cnt = 0
-    
-    try:
-        while True:
-            # Get the next data line
-            line = next(data_generator)
-            cnt = cnt + 1
-            msg = mqtt_topic + "," + line + str(cnt)
-            client.publish(mqtt_topic,msg)
-            print(f"Sent to MQTT broker={mqtt_broker} in topic={mqtt_topic} msg={msg}")
-            time.sleep(sim_interval)
-            
-    except KeyboardInterrupt:
-        print("Program terminated.")
-    finally:
-        client.loop_stop()
-        client.disconnect()
-
-if __name__ == "__main__":
-    # Load configuration from YAML
-    config = load_config()
-    
-    # Argument parser for configuration
-    parser = argparse.ArgumentParser(description="Simulate serial data and publish to MQTT.")
-    parser.add_argument("--random", action="store_true", help="Use random data instead of predefined simulation data")
-    parser.add_argument("--mqtt_broker", type=str, default=config.get('mqtt', {}).get('broker', "localhost"), help="MQTT broker address")
-    parser.add_argument("--mqtt_port", type=int, default=config.get('mqtt', {}).get('port', 1883), help="MQTT port")
-    parser.add_argument("--mqtt_topic", type=str, default=config.get('mqtt', {}).get('topic', "serial2MQTT"), help="MQTT topic to publish data")
-    parser.add_argument("--sim_interval", type=int, default=config.get('sim', {}).get('interval', 1), help="Interval in seconds for sending data")
-    args = parser.parse_args()
-    
-    # Run main with configuration from YAML and/or command line arguments
-    main(
-        use_random_data=args.random,
-        mqtt_broker=args.mqtt_broker,
-        mqtt_port=args.mqtt_port,
-        mqtt_topic=args.mqtt_topic,
-        sim_interval=args.sim_interval
-    ) 
\ No newline at end of file
diff --git a/serial_to_mqtt_bridge/serial_to_mqtt.exe b/serial_to_mqtt_bridge/susGatewayApp.exe
similarity index 70%
rename from serial_to_mqtt_bridge/serial_to_mqtt.exe
rename to serial_to_mqtt_bridge/susGatewayApp.exe
index 4b7bc4f522f449d3be072b527729cd47d6ec882a..e7d106a64dc7649e37d3ab13425bde7706b95266 100644
Binary files a/serial_to_mqtt_bridge/serial_to_mqtt.exe and b/serial_to_mqtt_bridge/susGatewayApp.exe differ
diff --git a/serial_to_mqtt_bridge/sustronics_logo_lowres.png b/serial_to_mqtt_bridge/sustronics_logo_lowres.png
new file mode 100644
index 0000000000000000000000000000000000000000..9503d089fa8c3d8e6426c108f35a9f7273c888bf
Binary files /dev/null and b/serial_to_mqtt_bridge/sustronics_logo_lowres.png differ