add: timestamped logs, clean shut down and flush with CTRL+C, print to file.
This commit is contained in:
@@ -1,65 +1,77 @@
|
|||||||
import serial
|
import serial
|
||||||
import threading
|
import threading
|
||||||
import time
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
REAL_PORT = "COM5" # MiniMate hardware
|
PORT_A = "COM5" # Real device
|
||||||
VIRTUAL_PORT = "COM4" # Bridge side of COM3<->COM4 pair
|
PORT_B = "COM4" # Virtual port for Blastware
|
||||||
BAUD = 38400
|
BAUD = 38400
|
||||||
|
|
||||||
|
class SessionLogger:
|
||||||
|
def __init__(self):
|
||||||
|
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
self.filename = f"s3_session_{ts}.log"
|
||||||
|
self.file = open(self.filename, "w", buffering=1)
|
||||||
|
print(f"[LOG] Writing session log to {self.filename}")
|
||||||
|
|
||||||
def hex_dump(data):
|
def log(self, direction, data):
|
||||||
return " ".join(f"{b:02X}" for b in data)
|
now = datetime.datetime.now().strftime("%H:%M:%S.%f")[:-3]
|
||||||
|
hex_string = " ".join(f"{b:02X}" for b in data)
|
||||||
|
line = f"[{now}] [{direction}] {hex_string}"
|
||||||
|
print(line)
|
||||||
|
self.file.write(line + "\n")
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
print("[LOG] Closing session log")
|
||||||
|
self.file.close()
|
||||||
|
|
||||||
|
|
||||||
def forward(src, dst, label):
|
def forward(src, dst, direction, logger):
|
||||||
while True:
|
try:
|
||||||
try:
|
while True:
|
||||||
data = src.read(1024) # blocking read
|
data = src.read(src.in_waiting or 1)
|
||||||
if data:
|
if data:
|
||||||
print(f"[{label}] {hex_dump(data)}")
|
logger.log(direction, data)
|
||||||
dst.write(data)
|
dst.write(data)
|
||||||
except serial.SerialException as e:
|
except Exception as e:
|
||||||
print(f"[{label}] Serial error: {e}")
|
print(f"[ERROR] {direction}: {e}")
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[{label}] Unexpected error: {e}")
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print("Opening ports...")
|
print("Opening ports...")
|
||||||
|
|
||||||
real = serial.Serial(
|
ser_a = serial.Serial(PORT_A, BAUD, timeout=0)
|
||||||
REAL_PORT,
|
ser_b = serial.Serial(PORT_B, BAUD, timeout=0)
|
||||||
BAUD,
|
|
||||||
timeout=0.1, # IMPORTANT: not zero
|
print(f"Connected: {PORT_A} <-> {PORT_B}")
|
||||||
write_timeout=0.1
|
|
||||||
|
logger = SessionLogger()
|
||||||
|
|
||||||
|
t1 = threading.Thread(
|
||||||
|
target=forward,
|
||||||
|
args=(ser_b, ser_a, "BLASTWARE -> S3", logger),
|
||||||
|
daemon=True
|
||||||
)
|
)
|
||||||
|
|
||||||
virt = serial.Serial(
|
t2 = threading.Thread(
|
||||||
VIRTUAL_PORT,
|
target=forward,
|
||||||
BAUD,
|
args=(ser_a, ser_b, "S3 -> BLASTWARE", logger),
|
||||||
timeout=0.1,
|
daemon=True
|
||||||
write_timeout=0.1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
print(f"Connected: {REAL_PORT} <-> {VIRTUAL_PORT}")
|
|
||||||
|
|
||||||
t1 = threading.Thread(target=forward, args=(virt, real, "BLASTWARE -> S3"), daemon=True)
|
|
||||||
t2 = threading.Thread(target=forward, args=(real, virt, "S3 -> BLASTWARE"), daemon=True)
|
|
||||||
|
|
||||||
t1.start()
|
t1.start()
|
||||||
t2.start()
|
t2.start()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
pass
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Stopping bridge...")
|
print("\n[INFO] Ctrl+C detected, shutting down...")
|
||||||
real.close()
|
finally:
|
||||||
virt.close()
|
logger.close()
|
||||||
sys.exit(0)
|
ser_a.close()
|
||||||
|
ser_b.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user