diff --git a/drivers/drivers/.gitignore b/drivers/drivers/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4fa751b48173247e0bb741cfe0ad965aef53c177
--- /dev/null
+++ b/drivers/drivers/.gitignore
@@ -0,0 +1,2 @@
+.secrets.json
+__pycache__
\ No newline at end of file
diff --git a/drivers/drivers/loopReadout.bat b/drivers/drivers/loopReadout.bat
new file mode 100644
index 0000000000000000000000000000000000000000..6ef5c8266e2abc09efc5f96cdfae6dd27267ca94
--- /dev/null
+++ b/drivers/drivers/loopReadout.bat
@@ -0,0 +1,16 @@
+setlocal enabledelayedexpansion
+@echo off
+set "filename=tempfile"
+
+:loop
+python readout.py elo > tempfile
+cls
+set "content="
+for /f "delims=" %%a in ('type "%filename%"') do (
+    set "line=%%a"
+    echo !line!
+)
+:: del tempfile
+timeout /T 12 /nobreak > nul
+goto loop
+endlocal
\ No newline at end of file
diff --git a/drivers/drivers/read_out_pid.py b/drivers/drivers/read_out_pid.py
new file mode 100644
index 0000000000000000000000000000000000000000..567f17928106e055acb1edf96aaaaf974344dda0
--- /dev/null
+++ b/drivers/drivers/read_out_pid.py
@@ -0,0 +1,11 @@
+import pidcontroller
+
+controller = pidcontroller.PidController('COM5')
+responses = []
+requests = ['t', 'p', 'v', 'o', 's']
+
+for r in requests:
+    responses.append(controller._sendCommand(r))
+
+for i in range(len(requests)):
+    print(f"{requests[i]} -> {responses[i]}")
\ No newline at end of file
diff --git a/drivers/drivers/readout.py b/drivers/drivers/readout.py
new file mode 100644
index 0000000000000000000000000000000000000000..967ddf1af3b84bd01829c7310b5c410869673a81
--- /dev/null
+++ b/drivers/drivers/readout.py
@@ -0,0 +1,117 @@
+import time
+import element
+import pqwsw2
+import rl20001
+import pidcontroller
+import sys
+
+def readoutController(controller):
+    temps = controller.getTemperatures()
+    coeffs = controller.getPidCoeff()
+    pid = controller.getPropIntDer()
+    output = controller.getOutput()
+    setpoint = controller.getSetpoint()
+    returnString = ""
+
+    returnString += f"PID Controller:\n"
+    returnString += f"\tCurrent Temperatures: \n"
+    returnString += f"\t\tloop: {temps[0]:.6f} °C\n"
+    returnString += f"\t\tool1: {temps[1]:.6f} °C\n"
+    returnString += f"\t\tool2: {temps[2]:.6f} °C\n"
+    returnString += f"\t\tool3: {temps[3]:.6f} °C\n"
+    returnString += f"\t\tool4: {temps[4]:.6f} °C\n"
+    returnString += f"\tPID Coefficients:\n"
+    returnString += f"\t\tKp: {coeffs[0]:>10.6f}\n"
+    returnString += f"\t\tKi: {coeffs[1]:>10.6f}\n"
+    returnString += f"\t\tKd: {coeffs[2]:>10.6f}\n"
+    returnString += f"\tCurrent PID Values:\n"
+    returnString += f"\t\tP: {pid[0]:>10.6f}\n"
+    returnString += f"\t\tI: {pid[1]:>10.6f}\n"
+    returnString += f"\t\tD: {pid[2]:>10.6f}\n"
+    returnString += f"\tCurrent control output:\n"
+    returnString += f"\t\t{output:.6f}\n"
+    returnString += f"\tCurrent Setpoint:\n"
+    returnString += f"\t\t{setpoint:.6f}\n"
+
+    return returnString
+
+def readoutSwitch(switch):
+    power = switch.getPower()
+    temperature = switch.getTemperature()
+    state = switch.getState()
+    returnString = ""
+
+    returnString += f"PQWSW2 WIFI Switch:\n"
+    returnString += f"\tState:\n"
+    returnString += f"\t\t{state}\n"
+    returnString += f"\tCurrent Temperature:\n"
+    returnString += f"\t\t{temperature:.6f} °C\n"
+    returnString += f"\tCurrent Powerdraw:\n"
+    returnString += f"\t\t{power} W\n"
+
+    return returnString
+
+def readoutRelays(relays):
+    returnString = ""
+
+    returnString += f"RL20001 Numato Relay Board:\n"
+    returnString += f"\tState:\n"
+    if relays.getState():
+        returnString += f"\t\tTrue\n"
+    else:
+        returnString += f"\t\tFalse\n"
+
+    return returnString
+
+controllerString = ""
+switchString = ""
+relayString = ""
+
+connected = True
+try:
+    controller = pidcontroller.PidController('COM10')
+    controllerString = readoutController(controller)
+    controller.disconnect()
+except:
+    connected = False
+
+if not connected:
+    exit()
+
+connected = True
+try:
+    mySwitch = pqwsw2.PQWSW2('192.168.254.1')
+    switchString = readoutSwitch(mySwitch)
+except:
+    connected = False
+
+if not connected:
+    exit()
+
+connected = True
+try:
+    relay = rl20001.RL20001('COM4')
+    relayString = readoutRelays(relay)
+except:
+    connected = False
+
+if not connected:
+    exit()
+
+
+
+elementPrintString = controllerString + switchString + relayString
+if len(sys.argv) == 1:
+    myElementConnection = element.Element()
+    myElementConnection.warn("Manual Readout Triggered")
+    split = elementPrintString.split("\n")
+    for i in range(len(split)):
+        s = split[i]
+        s = "> " + s
+        srepped = s.replace("\t", "> ")
+        split[i] = srepped
+
+    for s in split:
+        myElementConnection.warn(s)
+        time.sleep(0.3)
+print(elementPrintString)
\ No newline at end of file
diff --git a/drivers/drivers/setup_pid_controller.py b/drivers/drivers/setup_pid_controller.py
new file mode 100644
index 0000000000000000000000000000000000000000..aaf2edbda27bd87f5b64a3edb3c2068594c6002a
--- /dev/null
+++ b/drivers/drivers/setup_pid_controller.py
@@ -0,0 +1,15 @@
+#this is the configuration that was found to be stable
+import pidcontroller
+
+controller = pidcontroller.PidController('COM10')
+
+responses = []
+
+responses.append(controller._sendCommand('P2.254;'))
+responses.append(controller._sendCommand('I0.0014;'))
+responses.append(controller._sendCommand('D100.348;'))
+responses.append(controller._sendCommand('N349.35;'))
+responses.append(controller._sendCommand('E0.5;'))
+responses.append(controller._sendCommand('S31.0;'))
+
+print(responses)
\ No newline at end of file
diff --git a/drivers/drivers/supervisor.bat b/drivers/drivers/supervisor.bat
new file mode 100644
index 0000000000000000000000000000000000000000..6f639c1a52083410ec4358c7a448bb9b8a22457a
--- /dev/null
+++ b/drivers/drivers/supervisor.bat
@@ -0,0 +1 @@
+python supervisor.py
\ No newline at end of file
diff --git a/drivers/drivers/supervisor.py b/drivers/drivers/supervisor.py
new file mode 100644
index 0000000000000000000000000000000000000000..947caa23d3ffc2ab5bfcac7301823dbb9561bf69
--- /dev/null
+++ b/drivers/drivers/supervisor.py
@@ -0,0 +1,107 @@
+import time
+import element
+import pqwsw2
+import rl20001
+
+warn_thresh = [31.5, 28.0, 35.0, 40.0, 30.0]
+shutdown_thresh = [32.0, 30.0, 45.0, 45.0, 32.0]
+
+
+mySwitch = pqwsw2.PQWSW2('192.168.254.1')
+relay = rl20001.RL20001('COM4')
+
+tries = 0
+while not mySwitch.connected and tries < 5:
+    time.sleep(1)
+    mySwitch = pqwsw2.PQWSW2('192.168.254.1')
+    tries += 1
+
+tries = 0
+while not relay.connected and tries < 5:
+    time.sleep(1)
+    relay = rl20001.RL20001('COM4')
+    tries += 1
+
+
+myElementConnection = element.Element()
+
+def handler():
+    #check if switch is available
+    safety_compromised = False
+    if (not mySwitch.connected):
+        #print("Switch disconnected")
+        myElementConnection.warn(f"Can't connect to PQWSW2")
+        safety_compromised = True
+    
+    if(not relay.connected):
+        #print("Relay disconnected")
+        myElementConnection.warn(f"Can't connect to RL20001.")
+        safety_compromised = True
+    
+    if(not mySwitch.connected and not relay.connected):
+        #print("Switch and Relay disconnected")
+        myElementConnection.warn(f"All safety devices lost, automatic intervention disabled.")
+        safety_compromised = True
+
+    for repetitions_i in range(10):
+        try:
+            with open('templog.dat') as logfile:
+                line = logfile.readline()
+            logdatas = line.split(',')
+            timestamp_log = float(logdatas[0])
+            temps = [float(x) for x in logdatas[1:]]
+            print(f"Temperatures: {temps} °C")
+            #check for overtemperatures
+            overtemp_detected = False
+            for i,t in enumerate(temps):
+                if t >= warn_thresh[i]:
+                    #print("Over Thresh")
+                    myElementConnection.warn(f"Temperature {i} over warning threshold ({warn_thresh[i]:.4}°C) detected: {t:.5}°C")
+                if t >= shutdown_thresh[i]:
+                    #print("Over Shutdown")
+                    myElementConnection.warn(f"Temperature {i} over shutdown threshold ({shutdown_thresh[i]:.4}°C) detected: {t:.5}°C. Shutting down.")
+                    overtemp_detected = True
+                    if mySwitch.connected:
+                        mySwitch.turnOff()
+                    if relay.connected:
+                        relay.turnOff()
+            #check for old timestamp
+            old_timestamp_detected = False
+            now = time.time()
+            if now-timestamp_log > 60:
+                #no log for 1 minute
+                myElementConnection.warn(f"Latest temperature measurement is older than 1 minute ({now-timestamp_log} seconds). Will shut down at 900 seconds.")
+            if now-timestamp_log > 600:
+                #no log for 1 minute
+                myElementConnection.warn(f"Latest temperature measurement is older than 15 minutes ({now-timestamp_log} seconds). Shutting down")
+                old_timestamp_detected = True
+                if mySwitch.connected:
+                    mySwitch.turnOff()
+                if relay.connected:
+                    relay.turnOff()
+            if not overtemp_detected and not old_timestamp_detected:
+                #print("Have No Overtemp")
+                if mySwitch.connected:
+                    mySwitch.turnOn()
+                if relay.connected:
+                    relay.turnOn()
+
+
+            if safety_compromised:
+                #print("Safety Compromised")
+                myElementConnection.warn(f"Safety compromised. Temperatures: {temps} °C")
+            if repetitions_i > 0:
+                myElementConnection.warn(f"Logfile access recovered.")
+            
+            return
+        except Exception as expt:
+            myElementConnection.warn(f"Supervisor Error: {str(expt)}: try {repetitions_i+1}/10")
+            time.sleep(3.14159265)
+    
+    myElementConnection.warn(f"Temperature logfile inaccessible. Shutting down.")
+    mySwitch.turnOff()
+    relay.turnOff()
+
+
+
+handler()
\ No newline at end of file
diff --git a/drivers/drivers/tempfile b/drivers/drivers/tempfile
new file mode 100644
index 0000000000000000000000000000000000000000..8bd57f9414fdf064b0ec9c70e2ee4a9c932a0460
--- /dev/null
+++ b/drivers/drivers/tempfile
@@ -0,0 +1,30 @@
+PID Controller:
+	Current Temperatures: 
+		loop: 30.998979 °C
+		ool1: 23.452163 °C
+		ool2: 30.510729 °C
+		ool3: 31.085263 °C
+		ool4: 24.532361 °C
+	PID Coefficients:
+		Kp:   2.254000
+		Ki:   0.001400
+		Kd: 100.348000
+	Current PID Values:
+		P:   0.001009
+		I: 399.529812
+		D:  -0.000012
+	Current control output:
+		0.556895
+	Current Setpoint:
+		31.000000
+PQWSW2 WIFI Switch:
+	State:
+		True
+	Current Temperature:
+		25.730000 °C
+	Current Powerdraw:
+		60.1 W
+RL20001 Numato Relay Board:
+	State:
+		True
+
diff --git a/drivers/drivers/templog.dat b/drivers/drivers/templog.dat
new file mode 100644
index 0000000000000000000000000000000000000000..6308097e3a301170226fed760157964acb6a69ec
--- /dev/null
+++ b/drivers/drivers/templog.dat
@@ -0,0 +1 @@
+1709028399.7751513,30.999624,22.509048,31.170196,30.556627
\ No newline at end of file
diff --git a/drivers/drivers/tmp.txt b/drivers/drivers/tmp.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2f6cbdecbf9eb1a3adabfbafbb2bc48df51fbebb
--- /dev/null
+++ b/drivers/drivers/tmp.txt
@@ -0,0 +1,8 @@
+
+Pinging 192.168.1.1 with 32 bytes of data:
+Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
+
+Ping statistics for 192.168.1.1:
+    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
+Approximate round trip times in milli-seconds:
+    Minimum = 0ms, Maximum = 0ms, Average = 0ms