Initial: ContinuousTransponder wrapper for Kogger USBL

High-level Python wrapper around the upstream cosma-tech/kogger_acousticAntenna
driver. Configures a Kogger acoustic antenna as a permanent slave transponder
in a single start() call: address filter, echo filter, optional TDMA sync slot,
permanent response window, and Python callbacks for each ping received.

No modification to the upstream driver — only composes existing public methods
in the right order. Snapshot of upstream driver included read-only under driver/
for reference.

Includes:
- transponder_continu.py (302 lines): the wrapper class + CLI
- examples/auv_slave.py (79 lines): usage example with logging
- README.md: design rationale, usage, multi-AUV TDMA, watchdog, hardware wiring
- driver/: snapshot of cosma-tech/kogger_acousticAntenna at commit 1b539f9
  ('Add index slot for multi pinger', 2025-03-11)

Built for Cosma context (USV master + N AUVs slaves) following the design
conversation in Discord #ping-pong-ping (2026-04-27). See poulpe/ping-pong-ping
on Gitea for the interactive demo of the protocol.
This commit is contained in:
2026-04-27 22:08:44 +00:00
commit 9a158f5c5f
53 changed files with 7894 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
__pycache__/
*.pyc

143
README.md Normal file
View File

@@ -0,0 +1,143 @@
# Kogger USBL — mode transpondeur continu
Wrapper Python de haut niveau autour du driver Kogger `kogger_acousticAntenna` (cosma-tech) qui configure une antenne acoustique en **slave transpondeur permanent** : elle écoute en continu les pings adressés à son ID, répond automatiquement, ignore les autres, et expose un callback Python pour chaque ping reçu.
**Pas de re-armement par ping. Une seule init. Le device répond tant que le process tourne.**
Construit pour le contexte Cosma (USV master + N AUVs slaves), suite à la conversation Discord [#ping-pong-ping](https://gitea.nowyouknow.fr/poulpe/ping-pong-ping) du 2026-04-27 sur les schémas SS-TWR + écoute passive OWR.
---
## Pourquoi ce wrapper
Le driver Kogger upstream (`kogger_protocol_driver.KoggerSBPDevice`) expose toutes les commandes bas niveau nécessaires pour le mode transpondeur :
| Commande | Rôle |
|---|---|
| `set_usbl_transponder(enable)` | Ouvre/ferme la fenêtre de réponse acoustique. `True` = always (timeout `0xFFFFFFFF` µs). |
| `set_usbl_request_address_filter([...])` | Liste 8 adresses (0-7 ou `0xFF`=désactivé) pour lesquelles le device doit répondre. |
| `set_usbl_monitor_config(enable, echo_filter_response_us, echo_filter_request_us)` | Active la surveillance + le filtre d'écho (évite l'auto-déclenchement par réverbération). |
| `set_sync_mode(slot_total, slot_index, slot_duration, enable_delay)` | Enrôle le device dans un slot TDMA (utile en multi-slave). |
| `register_callback(ID_USBL_SOLUTION, fn)` | Branche un callback Python sur les frames USBL solution reçues. |
Mais il faut les composer dans **le bon ordre**, gérer les callbacks, et idéalement avoir un watchdog qui ré-applique la config si le device a redémarré ou que le master a été silencieux trop longtemps.
C'est exactement ce que `ContinuousTransponder` fait — un appel `start()` configure tout et le device entre en mode permanent.
## Architecture
```
.
├── README.md # ce fichier
├── transponder_continu.py # ★ wrapper haut niveau (zéro modif du driver)
├── examples/
│ └── auv_slave.py # exemple AUV slave avec logging
└── driver/ # snapshot read-only du driver upstream
├── kogger_protocol_driver.py (1509 lignes, 78 KB)
├── communication.py
├── interface.py
├── simulation_kogger.py
├── README.md
└── ...
```
**Aucune modification du driver Kogger d'origine.** Tout passe par les méthodes publiques. Quand cosma-tech publie une nouvelle version du driver, il suffit de remplacer le contenu de `driver/` — ce wrapper continue de fonctionner.
## Usage minimal
```python
from transponder_continu import ContinuousTransponder
t = ContinuousTransponder(port="/dev/ttyUSB0", my_address=2,
vehicle_name="AUV-2")
t.on_ping_received(lambda solution: print("ping →", solution))
t.start()
try:
t.run_forever()
finally:
t.stop()
```
## CLI directement
```bash
python3 transponder_continu.py --port /dev/ttyUSB0 --address 2
```
Options utiles :
```
--vehicle AUV-2 # étiquette pour les logs CSV du driver
--watchdog-s 15 # ré-applique la config si silence > 15 s
--slot-total 4 --slot-index 1 --slot-duration 2.0 # enrôle en TDMA
--echo-filter-us 400000 # 400 ms (défaut)
```
## Contenu de la trame transpondeur
Chaque fois que le master USV envoie un ping ciblé sur l'adresse de cet AUV :
1. Le hardware Kogger filtre par adresse (configuré par `set_usbl_request_address_filter`).
2. Si l'adresse correspond, le hardware **répond automatiquement** (le pong est généré par l'antenne, pas par Python — c'est rapide et déterministe).
3. Le driver émet une frame `ID_USBL_SOLUTION` (0x65) sur la sortie UART contenant la distance hardware-computed, le SNR, l'ID source.
4. Le wrapper appelle votre callback `on_ping_received(message)`.
5. Le state interne (`t.state.last_distance_m`, `last_snr`, `last_ping_id`, `pings_received`) est mis à jour.
Tout cela en boucle, sans intervention.
## Multi-AUV en TDMA
Si N AUVs partagent le canal et que le master scanne en round-robin, configurer chaque slave dans son propre slot évite les collisions de pong :
```python
ContinuousTransponder(
port="/dev/ttyUSB0",
my_address=2,
sync=SyncSlot(slot_total=4, slot_index=1, slot_duration=2.0),
)
```
→ AUV-2 ne répond que pendant son slot (slot_index=1, durée 2 s, cycle complet 8 s).
Convention proposée : `slot_index = my_address - 1`.
## Watchdog
Si on n'a rien reçu depuis `watchdog_timeout_s` secondes (et qu'on a au moins reçu un ping au démarrage), le wrapper ré-applique `set_usbl_transponder(enable=True)`. Couvre le cas où l'antenne Kogger reboot silencieusement et perd sa config.
```python
ContinuousTransponder(..., watchdog_timeout_s=15.0)
```
Off par défaut. Activer en prod si le master est censé pinger en continu.
## Hardware
Câblage Kogger côté antenne (recopié du README upstream pour référence) :
| Couleur | Signal |
|---|---|
| Brown | +V supply |
| Blue | GND |
| Green | UART RX (USBL ← host) |
| Yellow | UART TX (USBL → host) |
| Pink | GND (relié au bleu interne) |
| Gray | TRIGGER_IN |
| White | TRIGGER_OUT |
Connexion typique : `Pi4B → USB-UART converter → antenne Kogger`. Baudrate par défaut 921600.
## Limites / TODO
- [ ] Pas testé sur hardware réel (uniquement statique). Cf. test sur AUV-2 cosma au prochain déploiement.
- [ ] Pas de gestion de reconnexion USB-UART. Si le port disparaît, le process meurt — relancer côté systemd.
- [ ] Pas de support multi-port (un wrapper = une antenne). Pour multi-antennes sur un même Pi, instancier N `ContinuousTransponder` indépendants.
- [ ] L'écoute passive OWR (calcul de distance par non-ciblés à partir de `T_recv T_send`) n'est **pas** dans ce wrapper — elle nécessite une référence temporelle synchronisée USV↔AUVs et l'extraction de `T_send` depuis la trame du ping (pas exposé proprement par le driver upstream pour l'instant). À ajouter quand le besoin se présente.
- [ ] Ajouter un `start()` idempotent (actuellement appeler 2× réenroule les callbacks).
## Références
- Driver upstream : `git@github.com:cosma-tech/kogger_acousticAntenna.git`
- Page démo USBL DS-TWR + SS-TWR + OWR : <https://laboratoire.freeboxos.fr/ping-pong-ping/>
- Repo demo : `poulpe/ping-pong-ping` sur Gitea
- Conversation Discord d'origine : `#ping-pong-ping` (2026-04-27)

204
driver/README.md Normal file
View File

@@ -0,0 +1,204 @@
# Driver for Acoustic Antenna from Kogger
## Installations request
```
sudo apt update
sudo apt install python3-serial python3-loguru
```
# Kogger wires
Brown : supply (+)
Blue : ground (-)
Green : UART_RX (USBL side)
Yellow : UART_TX (USBL side)
Pink : ground (-), connected to the blue wire inside USBL
Gray : TRIGGER_IN (USBL side)
White : TRIGGER_OUT (USBL side)
## Files description
```
.
├── communication.py
├── interface.py
├── kogger_protocol_driver.py
└── test
├── test_kogger_driver.py
└── test_messages.bin
```
### communication.py
Test all functions from kogger\_protocol\_driver.py
### interface.py
Open a tkinter interface with all kogger\_protocol\_driver functions.
### kogger\_protocol\_driver.py
Driver for kogger device
### test folder
Contains tests function for kogger\_protocol\_driver.
#### Raspberry connection to Kogger
+-----------------+ +---------------+ +------------+
| | | | | |
| RASPBERRY PI 4 o---USB---o Convertisseur o---UART--o Antenne |
| | | USB-vers-UART | (TX,RX, | Kogger |
| | | | GND) | |
+-----------------+ +---------------+ +------------+
#### USV / Boat side
Launch :
```
cd test
./test_usv.py
```
#### AUV / Sub side
Launch :
```
cd test
./test_auv.py
```
# Analyze koggerApp
bb55 00 8b 11 00 xx 9cc3
Header Route Mode ID Length Payload Check
On boot :
A TX payload […]:
- bb55008b11009cc3
- bb5500931100a4db
- bb550083100100943e
- bb550083130096af
- bb550083120095ad
- bb550083150098b3
- bb550083140097b1
- bb5500832000a3c9
- bb55008b2000abe1
- bb5500932000b3f9
- bb55008318054a5d6bc9017c98
- bb55008b18054a5d6bc90184d8
- bb550
A RX payload:
- bb5500c91103049cc3401e
- bb5500d1110304a4db6876
- bb5500c1100304943eaa54
- bb5500c113030496af20d8
- bb5500c112030495ad1ccf
- bb5500c1150304 98b328ea
- bb5500c114030497b124e1
- bb5500412022000f00000000000078fe6b94000203000000000000000000000000000000000000000c32
- bb5500c120 0301a3c95144
- bb5500c9200305abe17da8
- bb550051200900000f0002000003018f00
- bb5500d1200305b3f9a500
- bb5500c11803047c98f4a6
- bb5500c91803 0484d84426
- bb5500d11803048a870111
## Conclusion :
Host : read 0x10, 0x11, 0x12, x13, x14, x15, x18, x20
0x10 : ID_DATASET
- bb550083100100943e
- bb5500c1100304943eaa54
0x11 : ID_DIST_SETU
0x12 : ID_CHART_SETUP
0x14 : ID_TRANSC
0x15 : ID_SND_SPD
0x18 : ID_UART
0x20 : ID_VERSION
# Kogger number
## USV to AUV
0 : DISARM Set AUV to DISARM
1 : DEPTH_HOLD Set AUV to fixed DEPTH
2 : Pause?
3 : MISSION_DEPTH Go to mission on DEPTH_HOLD
4 : MISSION Go to mission on ALT_HOLD
5 : SURFACE Go to SURFACE
6 : USBL_MODE_RESP Set USBL AUV as response
7 : USBL_MODE_TRAN Set USBL AUV as transponder
8 :
## AUV to USV
0 : DISARM AUV is DISARMED
1 : DEPTH_HOLD AUV is at fixed DEPTH
2 : Pause?
3 : MISSION_DEPTH AUV is in mission on DEPTH_HOLD
4 : MISSION AUV is in mission on ALT_HOLD
5 : SURFACE AUV is going to to SURFACE
6 : RECOVER_STUCK AUV is in recover_stuck or recover_stuck_random
7 : HARDWARE_FAIL AUV is in emergency and is going to surface
8 : EMERGENCY_STUCK AUV is stuck
## Kogger transfer in the air
-------------------------------------
Pinger sending | Responder receiving
0 | 5
1 | 2
2 | 1
3 | 4
4 | 3
5 | 0
6 | 6
7 | 7 OR 3 OR 5
8 | 8 OR 255
-------------------------------------
# Python info
## struct.unpack
- ? : bool (1B)
- b : int8 (1B)
- B : uint8 (1B)
- h : int16
- H : uint16
- i : int32
- I : uint32
- f : float (4B)
- d : double(8B)
- q : int64
- Q : uint64
# Test multi-antenna
From test/test_multi_antenna.py we can try a multi-antenna with time syncho.
## In spiral mode
### From USV/Slave
```
./test_multi_antenna.py /dev/ttyUSB0 0 2
```
### From AUV/Master
Where every lines is an AUV :
```
./test_multi_antenna.py /dev/ttyUSB1 1 2
./test_multi_antenna.py /dev/ttyUSB2 2 2
```

206
driver/communication.py Executable file
View File

@@ -0,0 +1,206 @@
#! /usr/bin/env python
# Test all commands from kogger driver
import sys
import time
import struct # For unpacking in callbacks, if needed
from loguru import logger
# Ensure the kogger_protocol_driver.py is in the Python path
try:
from kogger_protocol_driver import (
KoggerSBPDevice,
ID_TIMESTAMP,
# Add other specific IDs if you want specific callbacks for them
)
except ImportError:
logger.critical("Failed to import KoggerSBPDevice. Make sure kogger_protocol_driver.py is in the same directory or Python path.")
sys.exit(1)
# --- Loguru Setup for this script ---
logger.remove() # Remove default handler
LOG_LEVEL = "INFO" # Change to "DEBUG" for more detailed driver logs
logger.add(sys.stderr, level=LOG_LEVEL, format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>")
# --- Configuration for Real Device ---
SERIAL_PORT = "/dev/ttyUSB0"
BAUDRATE = 115200
DEVICE_ADDRESS = 0
REQUEST_INTERVAL_SECONDS = 10 # How often to run the full cycle of get requests
COMMAND_PAUSE_SECONDS = 0.01 # Small pause between individual commands
# --- Callback for Unsolicited Messages ---
def handle_unsolicited_message(frame):
"""Default callback for unsolicited messages."""
#logger.info(f"[UNSOLICITED MSG] ID: {frame['id']:#02x}, Mode: {frame['mode']:#02x}, Len: {frame['length']}, Payload: {frame['payload'].hex().upper()}")
if frame['id'] == ID_TIMESTAMP and frame.get('checksum_ok') and \
(frame['mode'] & 0x03) == 1 and frame['length'] == 4: # TYPE_CONTENT = 1
try:
timestamp = struct.unpack('<I', frame['payload'])[0]
logger.info(f" -> Unsolicited Timestamp: {timestamp} ms")
except struct.error as e:
logger.warning(f" -> Failed to unpack unsolicited timestamp: {e}")
# Add more specific parsing here if you expect other unsolicited messages frequently
def UpdateCounter(data, string, str_valid, str_timeout):
if data:
logger.success(" Success to get "+str(string)+":"+str(data))
str_valid.append(string)
else:
logger.warning(" Failed to get "+str(string))
str_timeout.append(string)
def main():
logger.info(f"Attempting to connect to Kogger device on {SERIAL_PORT} at {BAUDRATE} baud.")
driver = KoggerSBPDevice(
port=SERIAL_PORT,
baudrate=BAUDRATE,
device_address=DEVICE_ADDRESS,
default_timeout=0.1 # Wait up to 2s for a solicited response
)
if not driver.connect():
logger.error(f"Failed to connect to the device. Please check connections and permissions for {SERIAL_PORT}.")
return
driver.register_default_callback(handle_unsolicited_message)
logger.info("Registered default callback for unsolicited messages.")
try:
logger.info(f"Successfully connected. Starting data polling cycle every {REQUEST_INTERVAL_SECONDS} seconds. Press Ctrl+C to stop.")
loop_count = 0
while True:
str_valid = []
str_timeout = []
loop_count += 1
logger.info(f"\n========= Request Cycle {loop_count} =========")
# --- Measurement Data ---
logger.info("--- Requesting Timestamp (get_timestamp) ---")
data = driver.get_timestamp()
UpdateCounter(data, "get_timestamp", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Distance v0 (get_distance) ---")
data = driver.get_distance(version=0)
UpdateCounter(data, "get_distance(version=0)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Distance v1 (get_distance) ---")
data = driver.get_distance(version=1)
UpdateCounter(data, "get_distance(version=1)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Chart Data (get_chart_data) ---")
data = driver.get_chart_data()
UpdateCounter(data, "get_chart_data()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Attitude v0 - Euler (get_attitude) ---")
data = driver.get_attitude(version=0)
UpdateCounter(data, "get_attitude(version=0)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Attitude v1 - Quaternion (get_attitude) ---")
data = driver.get_attitude(version=1)
UpdateCounter(data, "get_attitude(version=1)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Temperature (get_temperature) ---")
data = driver.get_temperature()
UpdateCounter(data, "get_temperature()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
# --- Settings Data (GET methods) ---
UART_ID_TO_QUERY = 1 # Example UART ID from PDF
CHANNEL_ID_TO_QUERY = 0 # Example: 0 for "all active" or default dataset
logger.info(f"--- Requesting Dataset Config (Channel {CHANNEL_ID_TO_QUERY}) (get_dataset_config) ---")
data = driver.get_dataset_config(channel_id_to_request=CHANNEL_ID_TO_QUERY)
UpdateCounter(data, "get_dataset_config(channel_id_to_request=CHANNEL_ID_TO_QUERY)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Distance Setup (get_distance_setup) ---")
data = driver.get_distance_setup()
UpdateCounter(data, "get_distance_setup()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Chart Setup (get_chart_setup) ---")
data = driver.get_chart_setup()
UpdateCounter(data, "get_chart_setup()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Transceiver Settings (get_transceiver_settings) ---")
data = driver.get_transceiver_settings()
UpdateCounter(data, "get_transceiver_settings()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
data = driver.get_sound_speed()
UpdateCounter(data, "get_sound_speed()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info(f"--- Requesting UART Config v0 (Baudrate, UART {UART_ID_TO_QUERY}) (get_uart_config) ---")
data = driver.get_uart_config(uart_id=UART_ID_TO_QUERY, version=0)
UpdateCounter(data, "get_uart_config(uart_id=1, version=0)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info(f"--- Requesting UART Config v1 (Dev Address, UART {UART_ID_TO_QUERY}) (get_uart_config) ---")
data = driver.get_uart_config(uart_id=UART_ID_TO_QUERY, version=1)
UpdateCounter(data, "get_uart_config(uart_id=1, version=1)", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
# --- System Data (GET methods) ---
logger.info("--- Requesting Version Info (get_version_info) ---")
data = driver.get_version_info()
UpdateCounter(data, "get_version_info()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Mark Status (get_mark_status) ---")
data = driver.get_mark_status()
UpdateCounter(data, "get_mark_status()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting Diagnostics (get_diagnostics) ---")
data = driver.get_diagnostics()
UpdateCounter(data, "get_diagnostics()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
# --- Navigation Data (GET methods) ---
logger.info("--- Requesting Navigation Data (get_navigation_data) ---")
data = driver.get_navigation_data()
UpdateCounter(data, "get_navigation_data()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info("--- Requesting DVL Velocity Data (get_dvl_velocity_data) ---")
data = driver.get_dvl_velocity_data()
UpdateCounter(data, "get_dvl_velocity_data()", str_valid, str_timeout)
time.sleep(COMMAND_PAUSE_SECONDS)
logger.info(f"========= End of Request Cycle {loop_count}. Waiting {REQUEST_INTERVAL_SECONDS} seconds... =========")
logger.info("str_valid "+str(len(str_valid)) +"="+str(str_valid))
logger.info("str_timeout "+str(len(str_timeout))+"="+str(str_timeout))
time.sleep(REQUEST_INTERVAL_SECONDS)
except KeyboardInterrupt:
logger.info("Keyboard interrupt received. Stopping application...")
except Exception as e:
logger.critical(f"An unexpected error occurred during main loop: {e}", exc_info=True)
finally:
logger.info("Attempting to disconnect from the device...")
if 'driver' in locals() and driver and hasattr(driver, 'serial_conn') and driver.serial_conn :
if hasattr(driver.serial_conn, 'is_open') and driver.serial_conn.is_open:
driver.disconnect()
logger.info("Disconnected successfully.")
else: # Port was not open, but driver object exists
if hasattr(driver, '_reader_thread') and driver._reader_thread and driver._reader_thread.is_alive():
logger.info("Port was not open, ensuring reader thread is stopped if it was started.")
driver._stop_event.set()
driver._reader_thread.join(timeout=1.0)
else:
logger.info("Driver was not connected or instance not fully available for disconnect.")
if __name__ == "__main__":
main()
logger.info("Real device interaction script finished.")

841
driver/interface.py Executable file
View File

@@ -0,0 +1,841 @@
#! /usr/bin/env python
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog
import threading
import queue
import sys
import os
import time # For delays in "Get All"
# Ensure kogger_protocol_driver.py is accessible
try:
from loguru import logger
from kogger_protocol_driver import KoggerSBPDevice, KEY_CONFIRM
from kogger_protocol_driver import (
ID_TIMESTAMP, ID_DIST, ID_ATTITUDE, ID_TEMP, ID_UART, ID_FLASH, ID_BOOT,
ID_DATASET, ID_DIST_SETUP, ID_CHART_SETUP, ID_TRANSC, ID_SND_SPD,
ID_VERSION, ID_MARK, ID_DIAG, ID_NAV, ID_DVL_VEL, ID_IMU_SETUP, ID_UPDATE
)
except ImportError as e:
try:
import logging
_crit_logger = logging.getLogger(__name__)
_crit_handler = logging.StreamHandler(sys.stderr)
_crit_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
_crit_handler.setFormatter(_crit_formatter)
_crit_logger.addHandler(_crit_handler)
_crit_logger.setLevel(logging.CRITICAL)
_crit_logger.critical(f"Failed to import necessary modules: {e}. Make sure 'kogger_protocol_driver.py' is in the same directory or your PYTHONPATH, and 'loguru' is installed.")
except ImportError:
print(f"CRITICAL ERROR: Failed to import necessary modules: {e}. Make sure 'kogger_protocol_driver.py' is in the same directory or your PYTHONPATH, and 'loguru' is installed.")
sys.exit(1)
class TkinterLogHandler:
"""A handler for Loguru that redirects log messages to a Tkinter Text widget."""
def __init__(self, text_widget):
"""
Initializes the log handler.
:param text_widget: The Tkinter Text widget to which logs will be written.
"""
self.text_widget = text_widget
self.queue = queue.Queue()
self.text_widget.after(100, self._process_log_queue)
def write(self, message):
"""
Called by Loguru to write a log message. Adds message to an internal queue.
:param message: The log message string.
"""
self.queue.put(message)
def _process_log_queue(self):
"""Processes messages from the log queue and inserts them into the Text widget."""
try:
while not self.queue.empty():
message = self.queue.get_nowait()
if self.text_widget.winfo_exists():
self.text_widget.configure(state=tk.NORMAL)
self.text_widget.insert(tk.END, message)
self.text_widget.see(tk.END)
self.text_widget.configure(state=tk.DISABLED)
if self.text_widget.winfo_exists():
self.text_widget.after(100, self._process_log_queue)
except Exception as e:
print(f"Error in TkinterLogHandler: {e}")
class KoggerGuiApp:
"""Main application class for the Kogger SBP Control Panel GUI."""
def __init__(self, root_window):
"""
Initializes the main application window and its components.
:param root_window: The main Tkinter window (tk.Tk instance).
"""
self.root = root_window
self.root.title("Kogger SBP Control Panel")
self.root.geometry("950x750")
self.driver = None
self.command_queue = queue.Queue() # For results from driver threads to GUI
self.unsolicited_log_queue = queue.Queue() # For unsolicited messages to GUI log
self.log_text_widget = scrolledtext.ScrolledText(self.root, state=tk.DISABLED, height=10, wrap=tk.WORD, font=("Consolas", 9))
self.log_text_widget.pack(side=tk.BOTTOM, fill=tk.X, padx=5, pady=5)
self.configure_logging()
self.connection_frame = ttk.LabelFrame(self.root, text="Connection")
self.connection_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
self.notebook = ttk.Notebook(self.root)
self.notebook.pack(expand=True, fill="both", padx=5, pady=5)
self.tab_measurements = ttk.Frame(self.notebook)
self.tab_device_settings = ttk.Frame(self.notebook)
self.tab_data_settings = ttk.Frame(self.notebook)
self.tab_system = ttk.Frame(self.notebook)
self.tab_navigation = ttk.Frame(self.notebook)
self.notebook.add(self.tab_measurements, text="Measurements & Actions")
self.notebook.add(self.tab_device_settings, text="Device Settings")
self.notebook.add(self.tab_data_settings, text="Data Config")
self.notebook.add(self.tab_system, text="System & Flash")
self.notebook.add(self.tab_navigation, text="Navigation")
self._create_connection_widgets()
self._create_measurement_widgets()
self._create_device_settings_widgets()
self._create_data_settings_widgets()
self._create_system_widgets()
self._create_navigation_widgets()
self.root.protocol("WM_DELETE_WINDOW", self._on_closing)
self.root.after(100, self._process_command_queue)
self.root.after(100, self._process_unsolicited_log_queue)
def configure_logging(self):
"""Configures Loguru to output to console and the GUI's log widget."""
logger.remove()
logger.add(sys.stderr, level="DEBUG",
format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>")
if self.log_text_widget.winfo_exists():
log_handler = TkinterLogHandler(self.log_text_widget)
logger.add(log_handler, format="{time:HH:mm:ss} | {level: <7} | {message}", level="INFO")
logger.info("GUI Initialized. Logging configured.")
def _create_connection_widgets(self):
"""Creates widgets for the connection panel (port, baud, connect button)."""
ttk.Label(self.connection_frame, text="Port:").grid(row=0, column=0, padx=2, pady=2, sticky="w")
self.port_var = tk.StringVar(value="/dev/ttyUSB0")
ttk.Entry(self.connection_frame, textvariable=self.port_var, width=15).grid(row=0, column=1, padx=2, pady=2)
ttk.Label(self.connection_frame, text="Baud:").grid(row=0, column=2, padx=2, pady=2, sticky="w")
self.baud_var = tk.StringVar(value="115200")
ttk.Entry(self.connection_frame, textvariable=self.baud_var, width=10).grid(row=0, column=3, padx=2, pady=2)
ttk.Label(self.connection_frame, text="Addr:").grid(row=0, column=4, padx=2, pady=2, sticky="w")
self.addr_var = tk.StringVar(value="0")
ttk.Entry(self.connection_frame, textvariable=self.addr_var, width=3).grid(row=0, column=5, padx=2, pady=2)
self.connect_button = ttk.Button(self.connection_frame, text="Connect", command=self._toggle_connection)
self.connect_button.grid(row=0, column=6, padx=5, pady=2)
self.connection_status_var = tk.StringVar(value="Status: Disconnected")
ttk.Label(self.connection_frame, textvariable=self.connection_status_var).grid(row=0, column=7, padx=5, pady=2, sticky="w")
def _create_labeled_entry(self, parent, label_text, default_value="", width=10):
"""
Helper to create a labeled entry field.
:param parent: The parent widget.
:param label_text: Text for the label.
:param default_value: Default value for the entry.
:param width: Width of the entry field.
:return: Tuple (frame_containing_label_and_entry, string_var_for_entry, entry_widget).
"""
frame = ttk.Frame(parent)
ttk.Label(frame, text=label_text).pack(side=tk.LEFT, padx=(0,2))
var = tk.StringVar(value=default_value)
entry = ttk.Entry(frame, textvariable=var, width=width)
entry.pack(side=tk.LEFT)
return frame, var, entry
def _create_result_display(self, parent, label_text, width=50):
"""
Helper to create a display area (label + read-only entry) for command results.
:param parent: The parent widget.
:param label_text: Text for the label describing the result.
:param width: Width of the result display entry.
:return: Tuple (frame_containing_label_and_display, string_var_for_result_display).
"""
frame = ttk.Frame(parent)
ttk.Label(frame, text=label_text, anchor="w").pack(side=tk.LEFT, padx=(0, 2))
var = tk.StringVar(value="N/A")
entry = ttk.Entry(frame, textvariable=var, state="readonly", width=width)
entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
return frame, var
def _create_measurement_widgets(self):
"""Creates widgets for the 'Measurements & Actions' tab, including the 'Get All' button."""
parent = self.tab_measurements
row_idx = 0
self.get_all_button = ttk.Button(parent, text="🔄 Get All Available Data", command=self._get_all_data_sequentially)
self.get_all_button.grid(row=row_idx, column=0, columnspan=2, sticky="ew", padx=5, pady=10)
row_idx += 1
ttk.Separator(parent, orient='horizontal').grid(row=row_idx, column=0, columnspan=2, sticky='ew', pady=5)
row_idx +=1
# Timestamp
f, self.ts_result_var = self._create_result_display(parent, "Timestamp (ms):")
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Timestamp", command=lambda: self._run_driver_command(self.driver.get_timestamp, "Timestamp", self.ts_result_var)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
# Distance v0
f, self.dist_v0_result_var = self._create_result_display(parent, "Distance v0 (mm):")
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Distance (v0)", command=lambda: self._run_driver_command(self.driver.get_distance, "Distance v0", self.dist_v0_result_var, version=0)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
# Distance v1
f, self.dist_v1_result_var = self._create_result_display(parent, "Distance v1 (full):")
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Distance (v1)", command=lambda: self._run_driver_command(self.driver.get_distance, "Distance v1", self.dist_v1_result_var, version=1)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
# Attitude v0
f, self.att_v0_result_var = self._create_result_display(parent, "Attitude v0 (Euler):")
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Attitude (v0)", command=lambda: self._run_driver_command(self.driver.get_attitude, "Attitude v0", self.att_v0_result_var, version=0)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
# Attitude v1
f, self.att_v1_result_var = self._create_result_display(parent, "Attitude v1 (Quat):")
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Attitude (v1)", command=lambda: self._run_driver_command(self.driver.get_attitude, "Attitude v1", self.att_v1_result_var, version=1)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
# Temperature
f, self.temp_result_var = self._create_result_display(parent, "Temperature (°C):")
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Temperature", command=lambda: self._run_driver_command(self.driver.get_temperature, "Temperature", self.temp_result_var)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
# Chart Data
f, self.chart_result_var = self._create_result_display(parent, "Chart Info:", width=60)
f.grid(row=row_idx, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Chart Data", command=lambda: self._run_driver_command(self.driver.get_chart_data, "Chart Data", self.chart_result_var)).grid(row=row_idx, column=0, sticky="w", padx=5, pady=2)
row_idx += 1
def _create_device_settings_widgets(self):
"""Creates widgets for the 'Device Settings' tab (UART, Transceiver, Sound Speed)."""
parent = self.tab_device_settings
current_row = 0
# UART Config
uart_frame = ttk.LabelFrame(parent, text="UART Configuration (ID 0x18)")
uart_frame.grid(row=current_row, column=0, columnspan=3, sticky="ew", padx=5, pady=5, ipady=5)
current_row +=1
f_uart_id, self.uart_id_var, _ = self._create_labeled_entry(uart_frame, "UART ID:", "1", 3)
f_uart_id.grid(row=0, column=0, padx=2, pady=2, sticky="w")
f_uart_baud, self.uart_baud_var, _ = self._create_labeled_entry(uart_frame, "Set Baudrate:", "115200")
f_uart_baud.grid(row=1, column=0, padx=2, pady=2, sticky="w")
f_uart_addr, self.uart_new_addr_var, _ = self._create_labeled_entry(uart_frame, "Set New Dev Addr:", "0", 3)
f_uart_addr.grid(row=2, column=0, padx=2, pady=2, sticky="w")
ttk.Button(uart_frame, text="Set Baudrate (v0)", command=self._set_uart_baud).grid(row=1, column=1, padx=5, pady=2, sticky="ew")
ttk.Button(uart_frame, text="Set Dev Address (v1)", command=self._set_uart_dev_addr).grid(row=2, column=1, padx=5, pady=2, sticky="ew")
f_uart_get_v, self.uart_get_ver_var, _ = self._create_labeled_entry(uart_frame, "Get Info for Version (0/1):", "0", 2)
f_uart_get_v.grid(row=3, column=0, padx=2, pady=2, sticky="w")
ttk.Button(uart_frame, text="Get UART Config", command=self._get_uart_config).grid(row=3, column=1, padx=5, pady=2, sticky="ew")
f_uart_res, self.uart_get_result_var = self._create_result_display(uart_frame, "UART Get Result:")
f_uart_res.grid(row=4, column=0, columnspan=2, sticky="ew", padx=5, pady=2)
# Transceiver Settings
transc_frame = ttk.LabelFrame(parent, text="Transceiver Settings (ID 0x14)")
transc_frame.grid(row=current_row, column=0, columnspan=3, sticky="ew", padx=5, pady=5, ipady=5)
current_row += 1
f_freq, self.transc_freq_var, _ = self._create_labeled_entry(transc_frame, "Freq (kHz):", "675")
f_freq.grid(row=0, column=0)
f_pulse, self.transc_pulse_var, _ = self._create_labeled_entry(transc_frame, "Pulse Count:", "10")
f_pulse.grid(row=0, column=1)
self.transc_boost_var = tk.BooleanVar(value=True)
ttk.Checkbutton(transc_frame, text="Boost Enabled", variable=self.transc_boost_var).grid(row=0, column=2)
ttk.Button(transc_frame, text="Set Transceiver Cfg", command=self._set_transceiver_settings).grid(row=1, column=0, columnspan=3, sticky="ew")
f_transc_get, self.transc_get_result_var = self._create_result_display(transc_frame, "Current Transc:")
f_transc_get.grid(row=2, column=0, columnspan=2, sticky="ew")
ttk.Button(transc_frame, text="Get Transceiver Cfg", command=lambda: self._run_driver_command(self.driver.get_transceiver_settings, "Transceiver Settings", self.transc_get_result_var)).grid(row=2, column=2, sticky="ew")
# Sound Speed Settings
snd_spd_frame = ttk.LabelFrame(parent, text="Sound Speed (ID 0x15)")
snd_spd_frame.grid(row=current_row, column=0, columnspan=3, sticky="ew", padx=5, pady=5, ipady=5)
current_row += 1
f_sspd, self.sspd_var, _ = self._create_labeled_entry(snd_spd_frame, "Speed (mm/s):", "1500000")
f_sspd.grid(row=0, column=0)
ttk.Button(snd_spd_frame, text="Set Sound Speed", command=self._set_sound_speed).grid(row=0, column=1)
f_sspd_get, self.sspd_get_result_var = self._create_result_display(snd_spd_frame, "Current Speed:")
f_sspd_get.grid(row=1, column=0, sticky="ew")
ttk.Button(snd_spd_frame, text="Get Sound Speed", command=lambda: self._run_driver_command(self.driver.get_sound_speed, "Sound Speed", self.sspd_get_result_var)).grid(row=1, column=1)
def _create_data_settings_widgets(self):
"""Creates widgets for the 'Data Config' tab (Dataset, Distance Setup, Chart Setup)."""
parent = self.tab_data_settings
current_row = 0
dataset_frame = ttk.LabelFrame(parent, text="Dataset Configuration (ID 0x10)")
dataset_frame.grid(row=current_row, column=0, sticky="ew", padx=5, pady=5, ipady=5)
current_row += 1
f_ds_ch, self.ds_ch_id_var, _ = self._create_labeled_entry(dataset_frame, "Ch ID (0-2):", "0", 3)
f_ds_ch.grid(row=0, column=0)
f_ds_period, self.ds_period_var, _ = self._create_labeled_entry(dataset_frame, "Period (ms):", "0")
f_ds_period.grid(row=0, column=1)
f_ds_mask, self.ds_mask_var, _ = self._create_labeled_entry(dataset_frame, "Mask (hex):", "0x0")
f_ds_mask.grid(row=0, column=2)
ttk.Button(dataset_frame, text="Set Dataset Cfg", command=self._set_dataset_config).grid(row=1, column=0, columnspan=3, sticky="ew")
f_ds_get_ch, self.ds_get_ch_id_var, _ = self._create_labeled_entry(dataset_frame, "Get Ch ID:", "0", 3)
f_ds_get_ch.grid(row=2, column=0)
f_ds_get, self.ds_get_result_var = self._create_result_display(dataset_frame, "Current Dataset Cfg:")
f_ds_get.grid(row=3, column=0, columnspan=2, sticky="ew")
ttk.Button(dataset_frame, text="Get Dataset Cfg", command=self._get_dataset_config).grid(row=2, column=1, sticky="ew")
distsetup_frame = ttk.LabelFrame(parent, text="Distance Setup (ID 0x11)")
distsetup_frame.grid(row=current_row, column=0, sticky="ew", padx=5, pady=5, ipady=5)
current_row += 1
f_distoff, self.distsetup_offset_var, _ = self._create_labeled_entry(distsetup_frame, "Start Offset (mm):", "0")
f_distoff.grid(row=0, column=0)
f_distmax, self.distsetup_max_var, _ = self._create_labeled_entry(distsetup_frame, "Max Dist (mm):", "50000")
f_distmax.grid(row=0, column=1)
ttk.Button(distsetup_frame, text="Set Distance Setup", command=self._set_distance_setup).grid(row=0, column=2)
f_distsetup_get, self.distsetup_get_result_var = self._create_result_display(distsetup_frame, "Current Dist Setup:")
f_distsetup_get.grid(row=1, column=0, columnspan=2, sticky="ew")
ttk.Button(distsetup_frame, text="Get Distance Setup", command=lambda: self._run_driver_command(self.driver.get_distance_setup, "Distance Setup", self.distsetup_get_result_var)).grid(row=1, column=2)
chartsetup_frame = ttk.LabelFrame(parent, text="Chart Setup (ID 0x12)")
chartsetup_frame.grid(row=current_row, column=0, sticky="ew", padx=5, pady=5, ipady=5)
current_row += 1
f_cs_count, self.cs_count_var, _ = self._create_labeled_entry(chartsetup_frame, "Sample Count:", "1000")
f_cs_count.grid(row=0,column=0)
f_cs_resol, self.cs_resol_var, _ = self._create_labeled_entry(chartsetup_frame, "Sample Resol (mm):", "10")
f_cs_resol.grid(row=0,column=1)
f_cs_offset, self.cs_offset_var, _ = self._create_labeled_entry(chartsetup_frame, "Sample Offset:", "0")
f_cs_offset.grid(row=0,column=2)
ttk.Button(chartsetup_frame, text="Set Chart Setup", command=self._set_chart_setup).grid(row=1, column=0, columnspan=3, sticky="ew")
f_cs_get, self.cs_get_result_var = self._create_result_display(chartsetup_frame, "Current Chart Setup:")
f_cs_get.grid(row=2, column=0, columnspan=2, sticky="ew")
ttk.Button(chartsetup_frame, text="Get Chart Setup", command=lambda: self._run_driver_command(self.driver.get_chart_setup, "Chart Setup", self.cs_get_result_var)).grid(row=2, column=2)
def _create_system_widgets(self):
"""Creates widgets for the 'System & Flash' tab."""
parent = self.tab_system
current_row = 0
f_ver, self.ver_info_result_var = self._create_result_display(parent, "Version Info:", width=70)
f_ver.grid(row=current_row, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Version Info", command=lambda: self._run_driver_command(self.driver.get_version_info, "Version Info", self.ver_info_result_var)).grid(row=current_row, column=0, sticky="w", padx=5, pady=2)
current_row += 1
mark_frame = ttk.LabelFrame(parent, text="Device Mark (ID 0x21)")
mark_frame.grid(row=current_row, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
current_row += 1
self.mark_enable_var = tk.BooleanVar()
ttk.Checkbutton(mark_frame, text="Enable Mark (via ID_MARK SETTING)", variable=self.mark_enable_var).pack(side=tk.LEFT)
ttk.Button(mark_frame, text="Set Mark", command=self._set_mark).pack(side=tk.LEFT, padx=5)
f_mark_get, self.mark_get_result_var = self._create_result_display(mark_frame, "Mark Status:")
f_mark_get.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
ttk.Button(mark_frame, text="Get Mark Status", command=lambda: self._run_driver_command(self.driver.get_mark_status, "Mark Status", self.mark_get_result_var)).pack(side=tk.LEFT, padx=5)
f_diag, self.diag_result_var = self._create_result_display(parent, "Diagnostics:", width=70)
f_diag.grid(row=current_row, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Diagnostics", command=lambda: self._run_driver_command(self.driver.get_diagnostics, "Diagnostics", self.diag_result_var)).grid(row=current_row, column=0, sticky="w", padx=5, pady=2)
current_row += 1
flash_frame = ttk.LabelFrame(parent, text="Flash Operations (ID 0x23)")
flash_frame.grid(row=current_row, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
current_row += 1
ttk.Button(flash_frame, text="Save Settings to Flash", command=lambda: self._run_driver_command(self.driver.save_settings_to_flash, "Save Flash")).grid(row=0, column=0, padx=5, pady=2)
ttk.Button(flash_frame, text="Restore Settings from Flash", command=lambda: self._run_driver_command(self.driver.restore_settings_from_flash, "Restore Flash")).grid(row=0, column=1, padx=5, pady=2)
ttk.Button(flash_frame, text="Erase Flash Settings", command=lambda: self._run_driver_command(self.driver.erase_flash_settings, "Erase Flash")).grid(row=0, column=2, padx=5, pady=2)
boot_frame = ttk.LabelFrame(parent, text="Boot Operations (ID 0x24)")
boot_frame.grid(row=current_row, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
current_row += 1
ttk.Button(boot_frame, text="Reboot Device", command=self._reboot_device).grid(row=0, column=0, padx=5, pady=2)
ttk.Button(boot_frame, text="Run FW from Bootloader", command=lambda: self._run_driver_command(self.driver.run_firmware_from_bootloader, "Run FW")).grid(row=0, column=1, padx=5, pady=2)
imu_frame = ttk.LabelFrame(parent, text="IMU Calibration (ID 0x1B - In Dev)")
imu_frame.grid(row=current_row, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
current_row +=1
self.imu_gyro_var = tk.BooleanVar()
ttk.Checkbutton(imu_frame, text="Calibrate Gyro", variable=self.imu_gyro_var).pack(side=tk.LEFT, padx=5)
self.imu_accel_var = tk.BooleanVar()
ttk.Checkbutton(imu_frame, text="Calibrate Accel", variable=self.imu_accel_var).pack(side=tk.LEFT, padx=5)
ttk.Button(imu_frame, text="Start IMU Calibration", command=self._set_imu_calibration).pack(side=tk.LEFT, padx=5)
fw_frame = ttk.LabelFrame(parent, text="Firmware Update (ID 0x25 - Simplified)")
fw_frame.grid(row=current_row, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
current_row += 1
f_fw_pkt, self.fw_pkt_num_var, _ = self._create_labeled_entry(fw_frame, "Packet #:", "1", 5)
f_fw_pkt.pack(side=tk.LEFT)
f_fw_data, self.fw_data_var, _ = self._create_labeled_entry(fw_frame, "Data (hex):", "", 40)
f_fw_data.pack(side=tk.LEFT)
ttk.Button(fw_frame, text="Upload FW Chunk", command=self._upload_fw_chunk).pack(side=tk.LEFT, padx=5)
def _create_navigation_widgets(self):
"""Creates widgets for the 'Navigation' tab."""
parent = self.tab_navigation
current_row = 0
f_nav, self.nav_result_var = self._create_result_display(parent, "Navigation Data:", width=60)
f_nav.grid(row=current_row, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get Nav Data", command=lambda: self._run_driver_command(self.driver.get_navigation_data, "Nav Data", self.nav_result_var)).grid(row=current_row, column=0, sticky="w", padx=5, pady=2)
current_row += 1
f_dvl, self.dvl_result_var = self._create_result_display(parent, "DVL Velocity:", width=70)
f_dvl.grid(row=current_row, column=1, sticky="ew", padx=5, pady=2)
ttk.Button(parent, text="Get DVL Velocity", command=lambda: self._run_driver_command(self.driver.get_dvl_velocity_data, "DVL Velocity", self.dvl_result_var)).grid(row=current_row, column=0, sticky="w", padx=5, pady=2)
current_row += 1
# --- Driver Interaction & Threading ---
def _toggle_connection(self):
"""Toggles the device connection state (connect or disconnect)."""
if self.driver and self.driver.serial_conn and hasattr(self.driver.serial_conn, 'is_open') and self.driver.serial_conn.is_open:
self._disconnect_driver()
else:
self._connect_driver()
def _connect_driver(self):
"""Initiates connection to the device in a separate thread."""
port = self.port_var.get()
if not port:
messagebox.showerror("Error", "Serial port cannot be empty.")
return
try:
baud = int(self.baud_var.get())
addr = int(self.addr_var.get())
except ValueError:
messagebox.showerror("Error", "Baud rate and Address must be integers.")
return
self.driver = KoggerSBPDevice(port, baud, addr, default_timeout=1.5)
self.driver.register_default_callback(self._handle_unsolicited_from_driver)
self.connection_status_var.set("Status: Connecting...")
self.connect_button.config(text="Connecting...", state=tk.DISABLED)
threading.Thread(target=self._connect_thread_target, daemon=True).start()
def _connect_thread_target(self):
"""Target function for the connection thread. Handles actual connection attempt."""
if self.driver.connect():
self.command_queue.put(("status_update", ("Status: Connected", "green", "Disconnect")))
else:
self.command_queue.put(("status_update", ("Status: Failed to Connect", "red", "Connect")))
self.driver = None
def _disconnect_driver(self):
"""Initiates disconnection from the device in a separate thread."""
if self.driver:
logger.info("GUI: Disconnecting driver...")
if hasattr(self.driver, 'unregister_default_callback'):
self.driver.unregister_default_callback()
self.connect_button.config(text="Disconnecting...", state=tk.DISABLED)
threading.Thread(target=self._disconnect_thread_target, daemon=True).start()
else:
logger.info("GUI: Driver not initialized, cannot disconnect.")
def _disconnect_thread_target(self):
"""Target function for the disconnection thread."""
if self.driver:
self.driver.disconnect()
self.driver = None
self.command_queue.put(("status_update", ("Status: Disconnected", "black", "Connect")))
def _run_driver_command(self, driver_method_ref, command_name, result_var_target=None, *args, **kwargs):
"""
Executes a given driver method in a separate thread.
Posts its result to the GUI's command queue for UI updates.
:param driver_method_ref: The method of the `KoggerSBPDevice` instance to call.
:param command_name: A descriptive name for the command (for logging/display).
:param result_var_target: The Tkinter StringVar to update with the result.
:param args: Positional arguments for the driver method.
:param kwargs: Keyword arguments for the driver method.
"""
if not (self.driver and self.driver.serial_conn and hasattr(self.driver.serial_conn, 'is_open') and self.driver.serial_conn.is_open):
logger.warning(f"Cannot run '{command_name}': Not connected.")
messagebox.showwarning("Not Connected", "Please connect to the device first.")
if result_var_target: result_var_target.set("Error: Not Connected")
return
logger.info(f"GUI: Queuing execution for: {command_name} with args: {args}, kwargs: {kwargs}")
if result_var_target: result_var_target.set("Executing...")
thread = threading.Thread(target=self._command_thread_target,
args=(driver_method_ref, command_name, result_var_target) + args,
kwargs=kwargs, daemon=True)
thread.start()
def _command_thread_target(self, driver_method_ref, command_name, result_var_target, *args, **kwargs):
"""
Target function for the thread that executes a single driver command.
Posts the result or error to the GUI's command queue.
"""
try:
result = driver_method_ref(*args, **kwargs)
self.command_queue.put((command_name, result, result_var_target))
except Exception as e:
logger.error(f"Exception in driver command thread for '{command_name}': {e}", exc_info=True)
self.command_queue.put((command_name, f"Exception: {type(e).__name__}", result_var_target))
def _process_command_queue(self):
"""Processes results and status updates from the command queue to update the GUI."""
try:
while True:
message_type, data, target_var = self.command_queue.get_nowait()
if message_type == "status_update":
status_text, _, button_text = data
self.connection_status_var.set(status_text)
self.connect_button.config(text=button_text, state=tk.NORMAL)
logger.info(f"GUI: Connection status updated to '{status_text}'")
elif message_type == "get_all_finished":
if hasattr(self, 'get_all_button'): # Check if button exists
self.get_all_button.config(state=tk.NORMAL)
logger.info("GUI: 'Get All Available Data' sequence finished.")
elif message_type == "set_fetching_status": # New message type for "Get All"
# data is command_name_desc, target_var is the actual StringVar
command_name_desc = data
if target_var and isinstance(target_var, tk.StringVar):
target_var.set("Fetching...")
logger.debug(f"GUI: Set fetching status for {command_name_desc}")
else:
logger.warning(f"GUI: Invalid target_var for set_fetching_status of {command_name_desc}")
else: # Assumed to be a command result
command_name = message_type
result = data
result_var_target = target_var
logger.info(f"GUI: Received result for '{command_name}': {str(result)[:100]}")
if result_var_target and isinstance(result_var_target, tk.StringVar):
display_str = "N/A"
if isinstance(result, dict):
items = []
for k, v_item in result.items():
if isinstance(v_item, bytes): items.append(f"{k}: {v_item.hex().upper()[:20]}{'...' if len(v_item)>10 else ''}")
elif isinstance(v_item, float): items.append(f"{k}: {v_item:.3f}")
else: items.append(f"{k}: {v_item}")
display_str = ", ".join(items)
if len(display_str) > 70: display_str = display_str[:67] + "..."
elif isinstance(result, bool): display_str = "Success" if result else "Failed/False"
elif result is None: display_str = "No data / Failed / Timeout"
elif isinstance(result, (str, bytes)): display_str = result if isinstance(result, str) else result.hex().upper()
else: display_str = str(result)
result_var_target.set(display_str)
if result is True: logger.success(f"Command '{command_name}' reported success (True).")
elif result is False: logger.warning(f"Command '{command_name}' reported failure (False).")
elif result is None: logger.warning(f"Command '{command_name}' returned None (no data or error).")
except queue.Empty:
pass
except Exception as e:
logger.error(f"Error processing command queue: {e}", exc_info=True)
finally:
if self.root.winfo_exists():
self.root.after(100, self._process_command_queue)
def _handle_unsolicited_from_driver(self, frame):
""" Puts unsolicited messages (received by driver's callback) into a GUI-thread-safe queue. """
self.unsolicited_log_queue.put(frame)
def _process_unsolicited_log_queue(self):
"""Processes unsolicited messages from its queue and logs them via Loguru (to Tkinter widget)."""
try:
while True:
frame = self.unsolicited_log_queue.get_nowait()
logger.info(f"[UNSOLICITED In GUI] ID: {frame['id']:#02x}, Mode: {frame['mode']:#02x}, Payload: {frame['payload'].hex().upper()}")
except queue.Empty:
pass
finally:
if self.root.winfo_exists():
self.root.after(100, self._process_unsolicited_log_queue)
def _on_closing(self):
"""Handles the event when the main window is closed by the user."""
logger.info("Application closing initiated by user...")
if self.driver and self.driver.serial_conn and hasattr(self.driver.serial_conn, 'is_open') and self.driver.serial_conn.is_open:
logger.info("Attempting to disconnect driver on close...")
self._disconnect_driver() # This is now threaded, main window might close before it finishes
self.root.destroy()
logger.info("Application window destroyed.") # This log might go to console only
# --- Specific Command Handlers for SET operations & "Get All" ---
def _set_uart_baud(self):
"""Handles 'Set UART Baudrate' button click. Parses inputs and calls driver."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
uart_id = int(self.uart_id_var.get())
baud = int(self.uart_baud_var.get())
self._run_driver_command(self.driver.set_uart_config, "Set UART Baudrate",
uart_id=uart_id, baudrate=baud, new_dev_address=None)
except ValueError: messagebox.showerror("Input Error", "UART ID and Baudrate must be integers.")
def _set_uart_dev_addr(self):
"""Handles 'Set UART Device Address' button click. Parses inputs and calls driver."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
uart_id = int(self.uart_id_var.get())
addr = int(self.uart_new_addr_var.get())
if not (0 <= addr <= 15):
messagebox.showerror("Input Error", "Device Address must be between 0 and 15.")
return
self._run_driver_command(self.driver.set_uart_config, "Set UART Device Address",
uart_id=uart_id, new_dev_address=addr)
except ValueError: messagebox.showerror("Input Error", "UART ID and New Address must be integers.")
def _get_uart_config(self):
"""Handles 'Get UART Config' button click. Parses inputs and calls driver."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
uart_id = int(self.uart_id_var.get())
version_str = self.uart_get_ver_var.get()
version = int(version_str) if version_str else 0 # Default to version 0 if empty
if version not in [0,1]:
messagebox.showerror("Input Error", "Version must be 0 or 1.")
return
self._run_driver_command(self.driver.get_uart_config, f"Get UART Config v{version}", self.uart_get_result_var,
uart_id=uart_id, version=version)
except ValueError: messagebox.showerror("Input Error", "UART ID and Version must be integers.")
def _set_transceiver_settings(self):
"""Handles 'Set Transceiver Config' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
freq = int(self.transc_freq_var.get())
pulse = int(self.transc_pulse_var.get())
boost = self.transc_boost_var.get()
self._run_driver_command(self.driver.set_transceiver_settings, "Set Transceiver Settings",
frequency_khz=freq, pulse_count=pulse, boost_enabled=boost)
except ValueError: messagebox.showerror("Input Error", "Frequency and Pulse Count must be integers.")
def _set_sound_speed(self):
"""Handles 'Set Sound Speed' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
speed = int(self.sspd_var.get())
self._run_driver_command(self.driver.set_sound_speed, "Set Sound Speed", sound_speed_mm_s=speed)
except ValueError: messagebox.showerror("Input Error", "Sound speed must be an integer.")
def _set_dataset_config(self):
"""Handles 'Set Dataset Config' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
ch_id = int(self.ds_ch_id_var.get())
period = int(self.ds_period_var.get())
mask_str = self.ds_mask_var.get()
mask = int(mask_str, 16) if mask_str.lower().startswith("0x") else int(mask_str)
self._run_driver_command(self.driver.set_dataset_config, "Set Dataset Config",
channel_id=ch_id, channel_period_ms=period, channel_mask=mask)
except ValueError: messagebox.showerror("Input Error", "Channel ID, Period, and Mask must be valid integers (Mask can be hex '0x...').")
def _get_dataset_config(self):
"""Handles 'Get Dataset Config' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
ch_id_str = self.ds_get_ch_id_var.get()
ch_id = int(ch_id_str) if ch_id_str else 0 # Default to 0 if empty
self._run_driver_command(self.driver.get_dataset_config, "Get Dataset Config", self.ds_get_result_var,
channel_id_to_request=ch_id)
except ValueError: messagebox.showerror("Input Error", "Channel ID must be an integer.")
def _set_distance_setup(self):
"""Handles 'Set Distance Setup' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
offset = int(self.distsetup_offset_var.get())
max_dist = int(self.distsetup_max_var.get())
self._run_driver_command(self.driver.set_distance_setup, "Set Distance Setup",
start_offset_mm=offset, max_distance_mm=max_dist)
except ValueError: messagebox.showerror("Input Error", "Offset and Max Distance must be integers.")
def _set_chart_setup(self):
"""Handles 'Set Chart Setup' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
count = int(self.cs_count_var.get())
resol = int(self.cs_resol_var.get())
offset = int(self.cs_offset_var.get())
self._run_driver_command(self.driver.set_chart_setup, "Set Chart Setup",
sample_count=count, sample_resolution_mm=resol, sample_offset_num=offset)
except ValueError: messagebox.showerror("Input Error", "Sample Count, Resolution, and Offset must be integers.")
def _set_mark(self):
"""Handles 'Set Mark' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
enable = self.mark_enable_var.get()
if enable:
self._run_driver_command(self.driver.set_mark, "Set Mark (Request Enable)", result_var_target=self.mark_get_result_var, enable_mark=True)
else:
logger.warning("GUI: 'Set Mark' (disable) requested via ID_MARK checkbutton. Protocol docs suggest ID_MARK SETTING command is for setting the mark. Disabling the mark is usually done by host sending a normal command with the MODE.Mark bit cleared.")
messagebox.showinfo("Info", "The ID_MARK SETTING command primarily sets the mark. To clear it, the host typically sends any frame with the mark bit cleared in its MODE field.")
def _reboot_device(self):
"""Handles 'Reboot Device' button click with confirmation."""
if not (self.driver and self.driver.serial_conn and hasattr(self.driver.serial_conn, 'is_open') and self.driver.serial_conn.is_open):
messagebox.showwarning("Not Connected", "Please connect to the device first.")
return
if messagebox.askyesno("Confirm Reboot", "Are you sure you want to reboot the device? This will disconnect."):
logger.info("GUI: Initiating device reboot...")
self.connect_button.config(text="Rebooting...", state=tk.DISABLED)
threading.Thread(target=self._reboot_thread_target, daemon=True).start()
def _reboot_thread_target(self):
"""Target function for the reboot operation thread."""
success = False
if self.driver:
success = self.driver.reboot_device()
if success: # driver.reboot_device() calls disconnect internally
self.command_queue.put(("status_update", ("Status: Rebooted. Disconnected.", "black", "Connect")))
else:
self.command_queue.put(("status_update", ("Status: Reboot Failed", "red", "Connect")))
def _set_imu_calibration(self):
"""Handles 'Start IMU Calibration' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
gyro = self.imu_gyro_var.get()
accel = self.imu_accel_var.get()
if not gyro and not accel:
messagebox.showinfo("IMU Calibration", "No calibration type selected (Gyro or Accelerometer).")
return
self._run_driver_command(self.driver.set_imu_calibration, "IMU Calibration",
calibrate_gyro=gyro, calibrate_accelerometer=accel)
def _upload_fw_chunk(self):
"""Handles 'Upload FW Chunk' button click."""
if not self.driver: messagebox.showerror("Error", "Not connected!"); return
try:
pkt_num_str = self.fw_pkt_num_var.get()
if not pkt_num_str: messagebox.showerror("Input Error", "Packet number is required."); return
pkt_num = int(pkt_num_str)
data_hex = self.fw_data_var.get()
if not data_hex:
messagebox.showerror("Input Error", "Firmware data (hex) cannot be empty.")
return
data_bytes = bytes.fromhex(data_hex)
self._run_driver_command(self.driver.upload_firmware_update_chunk, "Upload FW Chunk",
packet_number=pkt_num, update_data_chunk=data_bytes)
except ValueError:
messagebox.showerror("Input Error", "Packet number must be int, data must be valid hex string (e.g., AABBCCDD).")
except Exception as e:
messagebox.showerror("Error", f"Failed to prepare FW chunk: {e}")
def _get_all_data_sequentially(self):
"""
Handles the 'Get All Available Data' button click.
Initiates a sequence of all implemented 'get_*' commands in a separate thread.
"""
if not (self.driver and self.driver.serial_conn and hasattr(self.driver.serial_conn, 'is_open') and self.driver.serial_conn.is_open):
messagebox.showwarning("Not Connected", "Please connect to the device first.")
return
logger.info("GUI: Starting 'Get All Available Data' sequence...")
if hasattr(self, 'get_all_button'): # Ensure button exists
self.get_all_button.config(state=tk.DISABLED)
threading.Thread(target=self._get_all_data_thread_target, daemon=True).start()
def _get_all_data_thread_target(self):
"""
Target function for the 'Get All Data' thread.
Sequentially calls driver methods and posts results to the command queue.
"""
# Ensure all these result_vars are defined in your _create_..._widgets methods
# Default UART ID and Dataset Channel ID for "Get All"
uart_id_for_get_all = int(self.uart_id_var.get() or "1")
dataset_ch_id_for_get_all = int(self.ds_get_ch_id_var.get() or "0")
commands_to_run_config = [
# (Driver Method, "Command Name for Log", Target StringVar, (args_tuple), {kwargs_dict})
(self.driver.get_timestamp, "Timestamp (All)", self.ts_result_var, (), {}),
(self.driver.get_distance, "Distance v0 (All)", self.dist_v0_result_var, (0,), {}),
(self.driver.get_distance, "Distance v1 (All)", self.dist_v1_result_var, (1,), {}),
(self.driver.get_chart_data, "Chart Data (All)", self.chart_result_var, (), {}),
(self.driver.get_attitude, "Attitude v0 (All)", self.att_v0_result_var, (0,), {}),
(self.driver.get_attitude, "Attitude v1 (All)", self.att_v1_result_var, (1,), {}),
(self.driver.get_temperature, "Temperature (All)", self.temp_result_var, (), {}),
(self.driver.get_dataset_config, "Dataset Cfg (All)", self.ds_get_result_var, (dataset_ch_id_for_get_all,), {}),
(self.driver.get_distance_setup, "Distance Setup (All)", self.distsetup_get_result_var, (), {}),
(self.driver.get_chart_setup, "Chart Setup (All)", self.cs_get_result_var, (), {}),
(self.driver.get_transceiver_settings, "Transceiver Cfg (All)", self.transc_get_result_var, (), {}),
(self.driver.get_sound_speed, "Sound Speed (All)", self.sspd_get_result_var, (), {}),
(self.driver.get_uart_config, "UART Cfg v0 (All)", self.uart_get_result_var, (uart_id_for_get_all, 0), {}),
(self.driver.get_uart_config, "UART Cfg v1 (All)", self.uart_get_result_var, (uart_id_for_get_all, 1), {}),
(self.driver.get_version_info, "Version Info (All)", self.ver_info_result_var, (), {}),
(self.driver.get_mark_status, "Mark Status (All)", self.mark_get_result_var, (), {}),
(self.driver.get_diagnostics, "Diagnostics (All)", self.diag_result_var, (), {}),
(self.driver.get_navigation_data, "Nav Data (All)", self.nav_result_var, (), {}),
(self.driver.get_dvl_velocity_data, "DVL Velocity (All)", self.dvl_result_var, (), {}),
]
for method_ref, cmd_name, res_var, args, kwargs in commands_to_run_config:
if hasattr(self.root, '_already_closed') and self.root._already_closed: # Check if window is closing
logger.info("'Get All' sequence aborted as window is closing.")
break
if not (self.driver and self.driver.serial_conn and hasattr(self.driver.serial_conn, 'is_open') and self.driver.serial_conn.is_open):
logger.warning("'Get All' sequence aborted: Not connected.")
break
logger.info(f"GUI 'Get All': Requesting '{cmd_name}'...")
# Send a message to GUI to update status to "Fetching..." for this specific res_var
self.command_queue.put(("set_fetching_status", cmd_name, res_var))
actual_result = None
try:
# This is the blocking call to the driver method.
# The driver method itself uses _execute_command which handles its own threading for send/receive.
# This _get_all_data_thread_target thread will wait here until method_ref completes.
actual_result = method_ref(*args, **kwargs)
except Exception as e:
logger.error(f"Exception during 'Get All' for '{cmd_name}': {e}", exc_info=True)
actual_result = f"Exception: {type(e).__name__}"
# Put the actual result (or error string) onto the queue for GUI update
self.command_queue.put((cmd_name, actual_result, res_var))
time.sleep(0.35) # Pause slightly longer between actual device commands
# Signal completion to re-enable the button
self.command_queue.put(("get_all_finished", None, None))
if __name__ == "__main__":
main_window = tk.Tk()
app = KoggerGuiApp(main_window)
try:
main_window.mainloop()
except Exception as e:
# This is a last resort if mainloop itself or _on_closing has an issue
print(f"CRITICAL GUI ERROR during mainloop or close: {e}")
if 'logger' in globals() or 'logger' in locals(): # Check if logger might exist
try:
logger.critical(f"Tkinter mainloop crashed or error during close: {e}", exc_info=True)
except: # logger itself might fail if stderr is redirected weirdly on crash
print("Logger failed during critical GUI error.")
# It's often good practice to re-raise or sys.exit(1) after such an error
# raise

File diff suppressed because it is too large Load Diff

51
driver/log_add_diff.py Executable file
View File

@@ -0,0 +1,51 @@
#! /usr/bin/env python
import csv
from datetime import datetime
def calculate_diff(input_file, output_file):
last_values = {}
output_rows = []
with open(input_file, 'r') as infile:
reader = csv.reader(infile)
for row in reader:
timestamp_str, metric, value_str = row
timestamp = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S.%f')
value = float(value_str)
output_rows.append(row)
if metric in last_values:
last_timestamp, last_value = last_values[metric]
time_diff = (timestamp - last_timestamp).total_seconds()
if time_diff > 0:
value_diff = value - last_value
if metric in ["Azimuth", "Elev"]:
value_diff = (value_diff + 90) % 180 - 90
value_diff = value_diff / time_diff
output_rows.append([timestamp_str, f"{metric}_diff", f"{value_diff:.6f}"])
last_values[metric] = (timestamp, value)
with open(output_file, 'w', newline='') as outfile:
writer = csv.writer(outfile)
writer.writerows(output_rows)
if __name__ == "__main__":
import sys
if len(sys.argv) != 3 and len(sys.argv) != 2:
print("Usage: python process_log.py <input_file> <output_file>")
sys.exit(1)
input_file = sys.argv[1]
if sys.argv == 3:
output_file = sys.argv[2]
else:
name, extension = input_file.rsplit('.', 1)
# Add "_diff" to the name and then add the extension back
output_file = f"{name}_diff.{extension}"
print("Generate new diff file :"+str(output_file))
calculate_diff(input_file, output_file)

View File

@@ -0,0 +1,64 @@
#! /usr/bin/env python
import sys
import subprocess
from pathlib import Path
import os # Import the 'os' module for path manipulation
# --- Configuration ---
# Add the names of the scripts you want to run in order.
scripts_to_run = ['log_to_csv.py', 'log_add_diff.py', 'log_to_human.py', 'log_merge_nav_usbl.py']
# -------------------
def main():
"""
Runs a list of scripts, modifying arguments for specific scripts as needed.
"""
# Get the absolute path of the directory where this launcher script is located.
launcher_dir = Path(__file__).parent.resolve()
# Get all arguments passed to this launcher.
args = sys.argv[1:]
if not args:
print("❌ Error: No arguments provided.")
print(f"Usage: python {sys.argv[0]} ARGUMENT1 ARGUMENT2 ...")
sys.exit(1)
print(f"🚀 Starting launcher with arguments: {', '.join(args)}\n")
# Iterate through each script defined in the list.
for script_name in scripts_to_run:
# Construct the full, absolute path to the target script.
script_path = launcher_dir / script_name
# For each script, iterate through each argument provided.
for arg in args:
# This is our new logic block
# ---------------------------------------------------------------
arg_for_script = arg # Default to the original argument
if script_name == 'log_add_diff.py' and arg.lower().endswith('.csv'):
# Split the argument into the part before the extension and the extension itself
basename, extension = os.path.splitext(arg)
# Create the new, modified argument
arg_for_script = f"{basename}_csv{extension}"
# ---------------------------------------------------------------
# The command now uses the potentially modified argument.
command = ['python', str(script_path), arg_for_script]
print(f"▶️ Running: {' '.join(command)}")
try:
subprocess.run(command, check=True, text=True)
except FileNotFoundError:
print(f"❌ Error: Script '{script_path}' not found.")
sys.exit(1)
except subprocess.CalledProcessError as e:
print(f"❌ Error running '{' '.join(command)}'. Returned code: {e.returncode}")
sys.exit(1)
print("\n✅ All scripts completed successfully!")
if __name__ == "__main__":
main()

111
driver/log_merge_nav_usbl.py Executable file
View File

@@ -0,0 +1,111 @@
#! /usr/bin/env python
import csv
import glob
import os
from datetime import datetime
import sys
def merge_log_files(nav_file, usbl_file, output_file):
"""
Merges navigation and USBL log files into a single CSV file with the format:
timestamp,data,value
Args:
nav_file (str): Path to the navigation log CSV file.
usbl_file (str): Path to the USBL log CSV file.
output_file (str): Path to the output merged CSV file.
"""
try:
all_lines = []
# Read the navigation log
with open(nav_file, 'r') as f:
reader = csv.reader(f)
header = next(reader) # Skip header
for row in reader:
all_lines.append(row)
# Remove last line if broken
if len(all_lines[-1]) != 3:
all_lines.pop()
# Read the USBL log
with open(usbl_file, 'r') as f:
reader = csv.reader(f)
for row in reader:
timestamp, data, value = row
if timestamp == "timestamp":
# Remove timestamp header if present (in merge from other merge)
continue
data = 'usbl_' + data
if data == 'usbl_ID':
value = str(int(float(value)))
all_lines.append([timestamp, data, value])
if len(all_lines[-1]) != 3:
all_lines.pop()
# Sort by timestamp
all_lines.sort(key=lambda x: datetime.strptime(x[0], '%Y-%m-%d %H:%M:%S.%f'))
# Write to CSV
with open(output_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['timestamp', 'data', 'value'])
writer.writerows(all_lines)
print(f"Successfully merged {nav_file} and {usbl_file} into {output_file}")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
try:
if len(sys.argv) == 2:
input_file_path = sys.argv[1]
target_directory = os.path.dirname(input_file_path)
if target_directory == "":
target_directory = "."
filename_only = os.path.basename(input_file_path)
base_name = "_".join(filename_only.split('_')[:3])
if not base_name:
raise ValueError("Could not parse base name from filename.")
print(f"Processing specific files for base name: {base_name}")
nav_log_file = os.path.join(target_directory, f'{base_name}_navigation_log.csv')
usbl_csv_file = os.path.join(target_directory, f'{base_name}_usbl_csv.csv')
output_filename = os.path.join(target_directory, f'{base_name}_merged_log.csv')
print(f"Merging {nav_log_file} and {usbl_csv_file} to {output_filename}")
merge_log_files(nav_log_file, usbl_csv_file, output_filename)
elif len(sys.argv) == 3:
nav_file = sys.argv[1]
usbl_file = sys.argv[2]
nav_basename = os.path.splitext(os.path.basename(nav_file))[0]
usbl_basename = os.path.splitext(os.path.basename(usbl_file))[0]
output_dir = os.path.dirname(nav_file)
if not output_dir:
output_dir = "."
output_filename = os.path.join(output_dir, f"{nav_basename}_{usbl_basename}_merged.csv")
print(f"Merging {nav_file} and {usbl_file} to {output_filename}")
merge_log_files(nav_file, usbl_file, output_filename)
else:
print("Error: Invalid number of arguments. Please provide 1 or 2 arguments.")
print("")
print("Usage:")
print(" 1 argument: python log_merge_nav_usbl.py <any_log_file_from_session>")
print(" (This will find navigation and usbl logs from the same session and merge them)")
print(" 2 arguments: python log_merge_nav_usbl.py <navigation_log_file.csv> <usbl_log_file.csv>")
print(" (This will merge the two specified files)")
sys.exit(1)
except FileNotFoundError as e:
print(f"Error: File not found: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")

203
driver/log_to_csv.py Executable file
View File

@@ -0,0 +1,203 @@
#!/usr/bin/env python3
"""
A script to parse Kogger SB protocol logs and convert UsblSolution messages
directly to a CSV file.
"""
import argparse
import ast
import csv
import struct
import sys
# Based on the Kogger SB protocol specification
ID_MAP = {
0x01: "ID_TIMESTAMP",
0x02: "ID_DIST",
0x03: "ID_CHART",
0x04: "ID_ATTITUDE",
0x05: "ID_TEMP",
0x10: "ID_DATASET",
0x11: "ID_DIST_SETUP",
0x12: "ID_CHART_SETUP",
0x14: "ID_TRANSC",
0x15: "ID_SND_SPD",
0x18: "ID_UART",
0x1B: "ID_IMU_SETUP",
0x20: "ID_VERSION",
0x21: "ID_MARK",
0x22: "ID_DIAG",
0x23: "ID_FLASH",
0x24: "ID_BOOT",
0x25: "ID_UPDATE",
0x64: "ID_NAV",
0x65: "ID_USBL_SOLUTION",
0x66: "ID_SIGNAL_ENCODER",
0x67: "ID_SIGNAL_DECODER",
0x68: "ID_USBL_CONTROL",
0x79: "ID_DVL_VEL",
# Aliases
102: "ID_SIGNAL_ENCODER",
103: "ID_SIGNAL_DECODER",
121: "ID_DVL_VEL",
}
def parse_route(route_byte):
"""Parses the ROUTE byte."""
dev_address = route_byte & 0b1111
return {"dev_address": dev_address}
def parse_mode(mode_byte):
"""Parses the MODE byte."""
type_val = mode_byte & 0b11
version = (mode_byte >> 3) & 0b111
return {
"type_val": type_val,
"version": version,
}
def parse_payload_structured(msg_id, mode, payload):
"""
Parses the payload and returns a structured dictionary for UsblSolution,
or a simple representation for other types.
"""
msg_name = ID_MAP.get(msg_id)
if msg_name == "ID_USBL_SOLUTION" and mode['version'] == 0:
if len(payload) == 152:
try:
fmt = '<BBHqIqfffffffffddffffddIff8f'
sol = struct.unpack(fmt, payload)
return {
"type": "UsblSolution",
"data": {
"ID": f"{sol[0]}",
"Dist": f"{sol[6]:.2f}",
"Azimuth": f"{sol[8]:.2f}",
"Elev": f"{sol[10]:.2f}",
"SNR": f"{sol[12]:.1f}"
}
}
except struct.error as e:
return {"type": "Error", "data": f"Failed to unpack UsblSolution: {e}"}
else:
return {"type": "Error", "data": f"UsblSolution payload wrong size ({len(payload)} bytes)"}
# Fallback for other message types
return {"type": msg_name or "Unknown", "data": payload.hex()}
def parse_message_structured(data):
"""Parses a full binary message frame and returns a dictionary."""
if len(data) < 8:
return {"error": "Message too short"}
try:
sync1, sync2, route_byte, mode_byte, msg_id, length = struct.unpack('<BBBBBB', data[:6])
except struct.error:
return {"error": "Could not unpack header"}
if sync1 != 0xBB or sync2 != 0x55:
return {"error": "Invalid sync bytes"}
header_end = 6
payload_end = header_end + length
checksum_end = payload_end + 2
if len(data) != checksum_end:
return {"error": f"Length mismatch. Header says {length}, but packet is {len(data)}"}
payload = data[header_end:payload_end]
mode_info = parse_mode(mode_byte)
payload_parsed = parse_payload_structured(msg_id, mode_info, payload)
return {
"msg_id": msg_id,
"payload_parsed": payload_parsed
}
def process_log_to_csv(input_file, output_file):
"""Reads a Kogger log, parses it, and writes UsblSolution data to a CSV."""
reassembly_buffer = b''
last_direction = None
try:
with open(input_file, 'r', newline='') as infile, open(output_file, 'w', newline='') as outfile:
csv_writer = csv.writer(outfile)
reader = csv.reader(infile)
for i, row in enumerate(reader):
if len(row) != 3:
continue
timestamp, direction, data_str = row
try:
data_bytes = ast.literal_eval(data_str)
if not isinstance(data_bytes, bytes):
raise TypeError("Not a bytes object")
except (ValueError, SyntaxError, TypeError):
continue
if direction != last_direction:
reassembly_buffer = b''
last_direction = direction
if direction != "RECEIVED":
continue
reassembly_buffer += data_bytes
while len(reassembly_buffer) >= 8: # Minimum message size
if not reassembly_buffer.startswith(b'\xbbU'):
sync_pos = reassembly_buffer.find(b'\xbbU')
if sync_pos == -1:
reassembly_buffer = b''
break
else:
reassembly_buffer = reassembly_buffer[sync_pos:]
if len(reassembly_buffer) < 6:
break
payload_len = reassembly_buffer[5]
full_msg_len = 6 + payload_len + 2 # header + payload + checksum
if len(reassembly_buffer) >= full_msg_len:
message_to_parse = reassembly_buffer[:full_msg_len]
parsed_data = parse_message_structured(message_to_parse)
if (parsed_data and not parsed_data.get("error") and
isinstance(parsed_data.get('payload_parsed'), dict)):
payload_info = parsed_data['payload_parsed']
if payload_info.get('type') == 'UsblSolution':
solution_data = payload_info['data']
for key, value in solution_data.items():
csv_writer.writerow([timestamp, key, value])
reassembly_buffer = reassembly_buffer[full_msg_len:]
else:
break
except FileNotFoundError:
print(f"Error: File not found at {input_file}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"An unexpected error occurred: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Convert Kogger SB protocol logs directly to a CSV file, extracting UsblSolution data."
)
input_file = sys.argv[1]
if sys.argv == 3:
output_file = sys.argv[2]
else:
name, extension = input_file.rsplit('.', 1)
# Add "_diff" to the name and then add the extension back
output_file = f"{name}_csv.{extension}"
print("Generate new csv file :"+str(output_file))
process_log_to_csv(input_file, output_file)

276
driver/log_to_human.py Executable file
View File

@@ -0,0 +1,276 @@
#!/usr/bin/env python3
"""
A script to parse and convert Kogger SB protocol logs into a human-readable format.
"""
import csv
import struct
import sys
import ast
import os
# Based on the Kogger SB protocol specification PDF and user-provided details.
# (From PDF page 5 and others)
ID_MAP = {
0x01: "ID_TIMESTAMP",
0x02: "ID_DIST",
0x03: "ID_CHART",
0x04: "ID_ATTITUDE",
0x05: "ID_TEMP",
0x10: "ID_DATASET",
0x11: "ID_DIST_SETUP",
0x12: "ID_CHART_SETUP",
0x14: "ID_TRANSC",
0x15: "ID_SND_SPD",
0x18: "ID_UART",
0x1B: "ID_IMU_SETUP",
0x20: "ID_VERSION",
0x21: "ID_MARK",
0x22: "ID_DIAG",
0x23: "ID_FLASH",
0x24: "ID_BOOT",
0x25: "ID_UPDATE",
0x64: "ID_NAV",
0x65: "ID_USBL_SOLUTION",
0x66: "ID_SIGNAL_ENCODER",
0x67: "ID_SIGNAL_DECODER",
0x68: "ID_USBL_CONTROL",
0x79: "ID_DVL_VEL",
# Some IDs have aliases
102: "ID_SIGNAL_ENCODER",
103: "ID_SIGNAL_DECODER",
121: "ID_DVL_VEL",
}
def parse_route(route_byte):
"""Parses the ROUTE byte."""
dev_address = route_byte & 0b1111
return {"dev_address": dev_address}
def parse_mode(mode_byte):
"""Parses the MODE byte."""
type_val = mode_byte & 0b11
type_map = {
0: "Reserved",
1: "CON:DEV→HST",
2: "SET:HST→DEV",
3: "GET:HST→DEV",
}
version = (mode_byte >> 3) & 0b111
mark = (mode_byte >> 6) & 0b1
response = (mode_byte >> 7) & 0b1
return {
"type": type_map.get(type_val, "Unknown"),
"type_val": type_val,
"version": version,
"mark": mark,
"response": response,
}
def parse_payload(msg_id, mode, payload):
"""Parses the payload based on message ID, mode, and version."""
msg_name = ID_MAP.get(msg_id)
# Check for generic RESP message first (PDF page 6)
if mode['type_val'] == 1 and len(payload) == 3: # CONTENT from DEVICE
try:
code, _check1, _check2 = struct.unpack('<BBB', payload)
resp_codes = {
0: "NONE", 1: "OK", 2: "ERR_CHECKSUMM", 3: "ERR_PAYLOAD",
4: "ERR_ID", 5: "ERR_VERSION", 6: "ERR_TYPE", 7: "ERR_KEY",
8: "ERR_RUNTIME"
}
if code in resp_codes:
return f"RESP: Status={resp_codes.get(code)} ({code})"
except struct.error:
pass # Not a valid RESP message, fall through
# Specific payload parsers
if msg_name == "ID_USBL_SOLUTION" and mode['version'] == 0:
# This is a GET request, no payload is expected.
if mode['type_val'] == 3 and len(payload) == 0:
return "Requesting UsblSolution"
if len(payload) == 152:
try:
# Format string derived from the user-provided Python code
fmt = '<BBHqIqfffffffffddffffddIff8f'
sol = struct.unpack(fmt, payload)
return (
f"Usbl: ID={sol[0]},"
f"Dist={sol[6]:.2f}m, "
f"Azimuth={sol[8]:.2f}deg, Elev={sol[10]:.2f}deg, "
f"SNR={sol[12]:.1f}")
except struct.error as e:
return f"Error: Failed to unpack UsblSolution: {e}"
else:
return f"Error: UsblSolution payload wrong size ({len(payload)} bytes)"
if msg_name == "ID_USBL_CONTROL":
if mode['version'] == 1 and len(payload) == 5:
timeout, address = struct.unpack('<IB', payload)
return f"AcousticPing: Timeout={timeout} us, Address={address}"
if mode['version'] == 3 and len(payload) == 4:
timeout, = struct.unpack('<I', payload)
return f"AutoResponseTimeout: Timeout={timeout} us"
if mode['version'] == 4 and len(payload) == 1:
address, = struct.unpack('<B', payload)
return f"AutoResponseAddressFilter: Address={address}"
if mode['version'] == 5 and len(payload) == 1:
address, = struct.unpack('<B', payload)
return f"AutoResponsePayloadAddress: Address={address}"
if msg_name == "ID_TEMP" and mode['type_val'] == 1 and len(payload) == 2:
temp_val, = struct.unpack('<h', payload)
return f"Temperature: {temp_val * 0.01:.2f} C"
if msg_name == "ID_DIST" and mode['type_val'] == 1:
if mode['version'] == 0 and len(payload) == 4:
distance, = struct.unpack('<I', payload)
return f"Distance: {distance} mm"
if mode['version'] == 1 and len(payload) == 6:
_num, _strong, distance, _width = struct.unpack('<BBIH', payload)
return f"Distance (v1): {distance} mm"
if msg_name == "ID_ATTITUDE" and mode['type_val'] == 1:
if mode['version'] == 0 and len(payload) == 6:
yaw, pitch, roll = struct.unpack('<hhh', payload)
return (
f"Attitude (Euler): Yaw={yaw*0.01:.2f}, "
f"Pitch={pitch*0.01:.2f}, Roll={roll*0.01:.2f} deg")
if mode['version'] == 1 and len(payload) == 16:
w0, w1, w2, w3 = struct.unpack('<ffff', payload)
return f"Attitude (Quaternion): w0={w0}, w1={w1}, w2={w2}, w3={w3}"
# Fallback for unknown or unhandled payloads
return f"Payload (hex): {payload.hex()}"
def parse_message(data):
"""Parses a full binary message frame."""
if len(data) < 8:
return "Error: Message too short"
try:
sync1, sync2, route_byte, mode_byte, msg_id, length = struct.unpack('<BBBBBB', data[:6])
except struct.error:
return "Error: Could not unpack header"
if sync1 != 0xBB or sync2 != 0x55:
return "Error: Invalid sync bytes"
header_end = 6
payload_end = header_end + length
checksum_end = payload_end + 2
if len(data) != checksum_end:
return f"Error: Length mismatch. Header says {length}, but packet is {len(data)}"
payload = data[header_end:payload_end]
route_info = parse_route(route_byte)
mode_info = parse_mode(mode_byte)
msg_name = ID_MAP.get(msg_id, f"Unknown ID (0x{msg_id:02x})")
payload_str = parse_payload(msg_id, mode_info, payload)
return (
f"ID:{msg_name[3:]:<14} | "
f"Type:{mode_info['type']:<11} | "
f"Vr:{mode_info['version']} | "
f"Ln:{length:<3} | "
f"Addr:{route_info['dev_address']} | "
f"{payload_str}"
)
def print_save(way, timestamp, message, outfile):
outfile.write(f"{timestamp} {way}: {message}\n")
def main(log_file):
"""Main function to read and process the log file."""
base, ext = os.path.splitext(log_file)
output_file = f"{base}_hum{ext}"
print(f"Input file: {log_file}")
print(f"Output file: {output_file}")
reassembly_buffer = b''
last_direction = None
try:
with open(log_file, 'r', newline='') as infile, open(output_file, 'w') as outfile:
reader = csv.reader(infile)
for i, row in enumerate(reader):
if len(row) != 3:
outfile.write(f"Skipping malformed row {i+1}: {row}\n")
continue
timestamp, direction, data_str = row
try:
data_bytes = ast.literal_eval(data_str)
if not isinstance(data_bytes, bytes):
raise TypeError("Not a bytes object")
except (ValueError, SyntaxError, TypeError):
outfile.write(f"{timestamp} {direction.ljust(8)}: Error: Could not parse data literal: {data_str}\n")
continue
# If the direction changes, reset the buffer.
if direction != last_direction:
reassembly_buffer = b''
last_direction = direction
if direction == "SENT":
# SENT messages are assumed to be complete
human_readable_msg = parse_message(data_bytes)
print_save("TX", timestamp, human_readable_msg, outfile)
continue
# Handle reassembly for RECEIVED messages
reassembly_buffer += data_bytes
while len(reassembly_buffer) >= 8: # Minimum possible message size
if not reassembly_buffer.startswith(b'\xbbU'):
# Buffer doesn't start with sync bytes, find the next sync sequence
sync_pos = reassembly_buffer.find(b'\xbbU')
if sync_pos == -1:
# No sync bytes, discard the whole buffer
reassembly_buffer = b''
break
else:
# Discard garbage before the sync bytes
reassembly_buffer = reassembly_buffer[sync_pos:]
if len(reassembly_buffer) < 6:
# Not enough data for a header
break
# Try to read the payload length
payload_len = reassembly_buffer[5]
full_msg_len = 6 + payload_len + 2 # header + payload + checksum
if len(reassembly_buffer) >= full_msg_len:
# We have a complete message
message_to_parse = reassembly_buffer[:full_msg_len]
human_readable_msg = parse_message(message_to_parse)
print_save("RX", timestamp, human_readable_msg, outfile)
# Keep the rest of the buffer for the next message
reassembly_buffer = reassembly_buffer[full_msg_len:]
else:
# Not enough data for a full message, wait for more
break
except FileNotFoundError:
print(f"Error: File not found at {log_file}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"An unexpected error occurred: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: python {sys.argv[0]} <log_file.csv>", file=sys.stderr)
sys.exit(1)
main(sys.argv[1])

139
driver/print_log.py Executable file
View File

@@ -0,0 +1,139 @@
#! /usr/bin/env python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
from matplotlib.widgets import Slider
import sys
# --- Thresholds for filtering ---
DIST_DIFF_THRESHOLD = 20000000000.0
AZIMUTH_DIFF_THRESHOLD = 20000000000.0
ELEV_DIFF_THRESHOLD = 20000000000.0
SNR_DIFF_THRESHOLD = 50000000000.0
def create_animated_plot(filepath):
"""
Creates an animated 3D plot of AUV movement with play/pause and speed control.
"""
# --- Data Loading and Processing ---
df = pd.read_csv(filepath, header=None, names=['Timestamp', 'Measurement', 'Value'])
df_pivot = df.pivot_table(index='Timestamp', columns='Measurement', values='Value', aggfunc='first').reset_index()
# --- Filtering based on thresholds ---
for col in ['Dist_diff', 'Azimuth_diff', 'Elev_diff', 'SNR_diff']:
if col in df_pivot.columns:
df_pivot[col] = pd.to_numeric(df_pivot[col])
df_pivot[col] = df_pivot[col].bfill()
if 'Dist_diff' in df_pivot.columns:
df_pivot = df_pivot[np.abs(df_pivot['Dist_diff']) <= DIST_DIFF_THRESHOLD]
if 'Azimuth_diff' in df_pivot.columns:
df_pivot = df_pivot[np.abs(df_pivot['Azimuth_diff']) <= AZIMUTH_DIFF_THRESHOLD]
if 'Elev_diff' in df_pivot.columns:
df_pivot = df_pivot[np.abs(df_pivot['Elev_diff']) <= ELEV_DIFF_THRESHOLD]
if 'SNR_diff' in df_pivot.columns:
df_pivot = df_pivot[np.abs(df_pivot['SNR_diff']) <= SNR_DIFF_THRESHOLD]
try:
df_pivot = df_pivot.dropna(subset=['Dist', 'Azimuth', 'Elev']).copy()
except:
df_pivot = df_pivot.dropna(subset=['Azimuth', 'Elev']).copy()
df_pivot = df_pivot.reset_index(drop=True)
try:
df_pivot['Dist'] = pd.to_numeric(df_pivot['Dist'])
except:
df_pivot['Dist'] = pd.to_numeric(10000)
pass
df_pivot['Azimuth'] = pd.to_numeric(df_pivot['Azimuth'])
df_pivot['Elev'] = pd.to_numeric(df_pivot['Elev'])
df_pivot['Azimuth_rad'] = np.deg2rad(df_pivot['Azimuth'])
df_pivot['Elev_rad'] = np.deg2rad(df_pivot['Elev'])
df_pivot['x'] = df_pivot['Dist'] * np.cos(df_pivot['Elev_rad']) * np.cos(df_pivot['Azimuth_rad'])
df_pivot['y'] = df_pivot['Dist'] * np.cos(df_pivot['Elev_rad']) * np.sin(df_pivot['Azimuth_rad'])
df_pivot['z'] = df_pivot['Dist'] * np.sin(df_pivot['Elev_rad'])
# --- Plot Setup ---
fig = plt.figure(figsize=(12, 10))
ax = fig.add_subplot(111, projection='3d')
plt.subplots_adjust(bottom=0.25) # Adjust subplot to make room for slider
# Set plot limits
ax.set_xlim(df_pivot['x'].min() - 1, df_pivot['x'].max() + 1)
ax.set_ylim(df_pivot['y'].min() - 1, df_pivot['y'].max() + 1)
ax.set_zlim(df_pivot['z'].min() - 1, df_pivot['z'].max() + 1)
# Initialize plot elements
ax.plot(df_pivot['x'], df_pivot['y'], df_pivot['z'], c='gray', linestyle='--', label='Full Trajectory')
auv_position, = ax.plot([], [], [], 'ro', markersize=10, label='AUV Position')
current_trajectory, = ax.plot([], [], [], c='b', label='Current Trajectory')
usv_position = ax.scatter(0, 0, 0, c='g', marker='^', s=100, label='USV')
ax.set_xlabel('X coordinate (meters)')
ax.set_ylabel('Y coordinate (meters)')
ax.set_zlabel('Z coordinate (meters)')
ax.legend()
# --- Animation ---
def update(frame):
auv_position.set_data([df_pivot['x'][frame]], [df_pivot['y'][frame]])
auv_position.set_3d_properties([df_pivot['z'][frame]])
current_trajectory.set_data(df_pivot['x'][:frame+1], df_pivot['y'][:frame+1])
current_trajectory.set_3d_properties(df_pivot['z'][:frame+1])
time_label = pd.to_datetime(df_pivot['Timestamp'][frame]).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
ax.set_title(f'AUV Movement at: {time_label}')
return auv_position, current_trajectory
fig.ani = FuncAnimation(fig, update, frames=len(df_pivot), blit=False, interval=50)
# --- Slider for Interval Control ---
axcolor = 'lightgoldenrodyellow'
ax_interval = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
s_interval = Slider(
ax=ax_interval,
label='Interval (ms)',
valmin=1,
valmax=1000,
valinit=50,
valstep=10
)
def update_interval(val):
if fig.ani.event_source:
fig.ani.event_source.stop()
new_interval = int(val)
fig.ani = FuncAnimation(fig, update, frames=len(df_pivot), blit=False, interval=new_interval)
fig.canvas.draw_idle()
s_interval.on_changed(update_interval)
fig.s_interval = s_interval
# --- Play/Pause Functionality ---
paused = False
def toggle_pause(event):
nonlocal paused
if event.key == ' ':
if paused:
fig.ani.resume()
else:
fig.ani.pause()
paused = not paused
fig.canvas.mpl_connect('key_press_event', toggle_pause)
plt.show()
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python animated_auv_tracker_fixed.py <path_to_data_file>")
sys.exit(1)
filepath = sys.argv[1]
create_animated_plot(filepath)

212
driver/simulation_kogger.py Normal file
View File

@@ -0,0 +1,212 @@
#!/usr/bin/env python
from loguru import logger
import os
import time
import csv
from datetime import datetime
import struct
# 0:Nothing, 1:Only important, 2:All
PRINT_LEVEL = 1
# PATH File for kogger log
# AUV log
#KOGGER_FILE = "2025-09-01_11-40-00_kogger_log_auv.csv"
# USV log
KOGGER_FILE = "2025-09-01_11-40-02_kogger_log_usv.csv"
# --- Frame parsing logic for simulation flexibility ---
SYNC1 = 0xBB
SYNC2 = 0x55
ID_USBL_CONTROL = 0x68
TYPE_SETTING = 2
def _parse_sim_frame(frame_bytes):
"""A simple parser for simulation matching flexibility."""
if not isinstance(frame_bytes, bytes) or len(frame_bytes) < 8:
return None
if frame_bytes[0] != SYNC1 or frame_bytes[1] != SYNC2:
return None
try:
s1, s2, route, mode, cmd_id, length = struct.unpack_from('<BBBBBB', frame_bytes, 0)
msg_type = mode & 0x03
version = (mode >> 3) & 0x07
return {
'id': cmd_id,
'type': msg_type,
'version': version,
'payload': frame_bytes[6:6+length]
}
except (struct.error, IndexError):
return None
# --- End of parsing logic ---
class simu_serial():
is_open = True
name = ""
log_messages = []
log_idx = 0
in_waiting = 1
kogger_next = None
received_write = 0
start_sim_time = None
start_log_time = None
def _print(text, level):
if level <= PRINT_LEVEL:
logger.debug(text)
def _parse_and_merge_csv(filename):
messages = []
script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, filename)
if not os.path.exists(file_path):
# Fallback to current dir if not found next to script
file_path = filename
with open(file_path, 'r') as f:
reader = csv.reader(f)
for row in reader:
ts_str, msg_type, msg_content = row
timestamp = datetime.strptime(ts_str, '%Y-%m-%d %H:%M:%S.%f')
try:
byte_msg = eval(msg_content)
except Exception as e:
simu_serial._print(f"Could not eval message content: {msg_content}, error: {e}", 1)
byte_msg = msg_content.encode()
messages.append({'timestamp': timestamp, 'type': msg_type, 'msg': byte_msg})
merged = []
i = 0
while i < len(messages):
msg = messages[i]
if msg['type'] == 'RECEIVED' and msg['msg'] == b'\xbb':
full_msg = b'\xbb'
ts = msg['timestamp']
i += 1
while i < len(messages) and messages[i]['type'] == 'RECEIVED' and messages[i]['msg'] != b'\xbb':
full_msg += messages[i]['msg']
i += 1
merged.append({'timestamp': ts, 'type': 'RECEIVED', 'msg': full_msg})
else:
merged.append(msg)
i += 1
return merged
def Serial(port, baudrate=921600, timeout=1):
logger.error("!!!!!!Init kogger in simulation mode!!!!!!!")
simu_serial.name = port
simu_serial.log_messages = simu_serial._parse_and_merge_csv(KOGGER_FILE)
if not simu_serial.log_messages:
logger.error(f"No messages loaded from {KOGGER_FILE}")
return simu_serial
simu_serial.log_idx = 0
simu_serial.start_sim_time = time.time()
simu_serial.start_log_time = simu_serial.log_messages[0]['timestamp']
return simu_serial
def close():
simu_serial._print("Close kogger", 1)
return True
def read(size=1):
if simu_serial.received_write == 1:
line = simu_serial.kogger_next
simu_serial.kogger_next = None
simu_serial.received_write = 0
simu_serial._print(f"read (from write): {line}", 2)
return line
if simu_serial.log_idx >= len(simu_serial.log_messages):
simu_serial._print("End of log file.", 1)
time.sleep(1)
return b''
next_msg = simu_serial.log_messages[simu_serial.log_idx]
log_time_elapsed = (next_msg['timestamp'] - simu_serial.start_log_time).total_seconds()
sim_time_elapsed = time.time() - simu_serial.start_sim_time
if sim_time_elapsed < log_time_elapsed:
sleep_duration = log_time_elapsed - sim_time_elapsed
if sleep_duration > 0:
time.sleep(sleep_duration)
# Re-check current message as time has passed
if simu_serial.log_idx >= len(simu_serial.log_messages):
return b''
next_msg = simu_serial.log_messages[simu_serial.log_idx]
if next_msg['type'] == 'RECEIVED':
simu_serial.log_idx += 1
simu_serial._print(f"read (unsolicited): {next_msg['msg']}", 2)
return next_msg['msg']
else: # SENT
return b''
def write(text):
simu_serial._print(f"Write: {text}", 2)
incoming_frame_info = _parse_sim_frame(text)
search_idx = simu_serial.log_idx
while search_idx < len(simu_serial.log_messages):
log_entry = simu_serial.log_messages[search_idx]
if log_entry['type'] == 'SENT':
match = False
# Check for flexible match on acoustic ping (USBL_CONTROL with state)
if (incoming_frame_info and
incoming_frame_info['id'] == ID_USBL_CONTROL and
incoming_frame_info['type'] == TYPE_SETTING and
incoming_frame_info['version'] == 1):
log_frame_info = _parse_sim_frame(log_entry['msg'])
if (log_frame_info and
log_frame_info['id'] == ID_USBL_CONTROL and
log_frame_info['type'] == TYPE_SETTING and
log_frame_info['version'] == 1):
simu_serial._print(f"Flexible match for USBL_CONTROL message. Incoming: {text.hex()}, Logged: {log_entry['msg'].hex()}", 2)
match = True
# Fallback to exact match for all other messages
if not match and log_entry['msg'] == text:
match = True
if match:
# Sync time
log_time_elapsed = (log_entry['timestamp'] - simu_serial.start_log_time).total_seconds()
simu_serial.start_sim_time = time.time() - log_time_elapsed
response_idx = search_idx + 1
while response_idx < len(simu_serial.log_messages):
if simu_serial.log_messages[response_idx]['type'] == 'RECEIVED':
simu_serial.kogger_next = simu_serial.log_messages[response_idx]['msg']
simu_serial.received_write = 1
# Advance log time to response time
log_time_elapsed_resp = (simu_serial.log_messages[response_idx]['timestamp'] - simu_serial.start_log_time).total_seconds()
sim_time_elapsed = time.time() - simu_serial.start_sim_time
if sim_time_elapsed < log_time_elapsed_resp:
sleep_duration = log_time_elapsed_resp - sim_time_elapsed
if sleep_duration > 0:
time.sleep(sleep_duration)
simu_serial.log_idx = response_idx + 1
return
response_idx += 1
logger.warning(f"No RECEIVED message found after SENT: {text}")
simu_serial.log_idx = search_idx + 1
return
search_idx += 1
logger.error(f"Unexpected SENT message: {text} from index {simu_serial.log_idx}")
def reset_output_buffer():
pass

153
driver/test/listen_to_antenna.py Executable file
View File

@@ -0,0 +1,153 @@
#! /usr/bin/env python
import time
import sys
from kogger_protocol_driver import KoggerSBPDevice, setup_logging
import json
# --- Script Configuration ---
# Set the desired logging level: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
LOG_LEVEL = "DEBUG"
# Default serial port if not provided via command line
DEFAULT_SERIAL_PORT = "/dev/ttyUSB0"
serial_speed = 921600
# --- Setup Logging ---
# Configure the logger for the Kogger driver module
setup_logging(LOG_LEVEL)
def print_message(message):
"""
This function is a callback that will be executed for each message
received from the antenna that is not a direct response to a command.
"""
print("Message = "+str(message))
parsed = json.loads(str(message).replace("nan", "'nan'").replace("'",'"'))
print("parsed="+str(parsed))
print(json.dumps(parsed, indent=2))
def check_all_getters(antenna):
"""
Calls all get_* methods on the antenna object and prints the results.
"""
print("\n--- Checking all getter methods ---")
# A list of all getter methods to call.
# Some methods require arguments, which are provided as tuples.
# (method_name, args_tuple)
getters_to_test = [
('get_timestamp', ()),
('get_distance', (0,)),
('get_distance', (1,)),
('get_chart_data', ()),
('get_attitude', (0,)), #!!OK
('get_attitude', (1,)),
('get_temperature', ()),
('get_dataset_config', (0,)),
('get_distance_setup', ()),
('get_chart_setup', ()),
('get_transceiver_settings', ()),
('get_sound_speed', ()),
('get_uart_config', (1, 0)), # uart_id=1, version=0
('get_uart_config', (1, 1)), # uart_id=1, version=1
('get_version_info', ()), #!! OK
('get_mark_status', ()), #!! OK
('get_diagnostics', ()),
('get_navigation_data', ()),
('get_dvl_velocity_data', ()),
('get_signal_encoder_data', ()),
('get_signal_decoder_data', ()),
('get_auto_response_timeout', ()),
('get_auto_response_filter', ()),
('get_auto_response_payload', ()),
('get_usbl_solution', ()),
]
for method_name, args in getters_to_test:
try:
method = getattr(antenna, method_name)
print(f"Calling {method_name}{args}...")
result = method(*args)
print(f"Result: {result}")
except Exception as e:
print(f"An error occurred while calling {method_name}: {e}")
print("-" * 20)
time.sleep(0.01) # Give the device a moment between commands
print("--- Finished checking all getter methods ---\n")
def main():
"""
Main function to connect to the Kogger antenna and listen for messages.
"""
# Determine the serial port to use
if len(sys.argv) > 1:
serial_port = sys.argv[1]
else:
serial_port = DEFAULT_SERIAL_PORT
print(f"No serial port provided. Using default: {serial_port}")
# Instantiate the driver
antenna = KoggerSBPDevice(serial_port, serial_speed, default_timeout=0.02)
try:
# Connect to the antenna
if not antenna.connect():
print(f"Failed to connect to the antenna on port {serial_port}", file=sys.stderr)
sys.exit(1)
#antenna.register_default_callback(print_message)
#time.sleep(20)
#exit()
#result = antenna.get_dataset_config(0)
result = antenna.set_auto_response_filter(0)
print("result="+str(result))
result = antenna.set_auto_response_timeout(0xffffffff)
print("result="+str(result))
result = antenna.set_auto_response_payload(0xff)
print("result="+str(result))
#exit()
antenna.register_default_callback(print_message)
for i in range(10000):
#result = antenna.send_acoustic_ping(i%9)
result = antenna.send_acoustic_ping(0)
print("sent "+str(i%9)+"result="+str(result))
result = antenna.set_auto_response_filter(0)
result = antenna.set_auto_response_timeout(0xffffffff)
result = antenna.set_auto_response_payload(0xff)
time.sleep(1)
exit()
print(f"Successfully connected to the antenna on {serial_port}.")
# Perform a one-time check of all getter functions
check_all_getters(antenna)
# Register the callback function to handle incoming messages
antenna.register_default_callback(print_message)
print("Listening for unsolicited messages... Press Ctrl+C to exit.")
# Keep the main thread alive to allow the background reader thread to run
time.sleep(5)
#exit()
while True:
time.sleep(10)
except KeyboardInterrupt:
print("\nExiting...")
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
finally:
# Ensure the connection is closed gracefully
print("Disconnecting from the antenna.")
antenna.disconnect()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,5 @@
2026-03-19 12:51:12.478 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-19_12-51-12_log_usv.log.
2026-03-19 12:51:12.478 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0, baudrate 921600, address 0
2026-03-19 12:51:12.479 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-19_12-51-12_AUV_usbl.csv
2026-03-19 12:51:12.480 | ERROR | kogger_protocol_driver:connect:317 - Error connecting to /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0: [Errno 2] could not open port /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0: [Errno 2] No such file or directory: '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0'
2026-03-19 12:51:12.480 | WARNING | kogger_protocol_driver:disconnect:341 - Not connected or already disconnected.

View File

@@ -0,0 +1,5 @@
2026-03-19 12:52:10.592 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-19_12-52-10_log_usv.log.
2026-03-19 12:52:10.593 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0, baudrate 921600, address 0
2026-03-19 12:52:10.593 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-19_12-52-10_AUV_usbl.csv
2026-03-19 12:52:10.594 | ERROR | kogger_protocol_driver:connect:317 - Error connecting to /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0: [Errno 2] could not open port /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0: [Errno 2] No such file or directory: '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0'
2026-03-19 12:52:10.594 | WARNING | kogger_protocol_driver:disconnect:341 - Not connected or already disconnected.

View File

@@ -0,0 +1,69 @@
2026-03-19 12:52:43.093386,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-19 12:52:43.094057,RECEIVED,"b'U'"
2026-03-19 12:52:43.095431,RECEIVED,"b'\x00A ""\x00\x0f\x00\x00\x00\x00\x00\x00\x9d\x0eDT\x00\x02\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf8'"
2026-03-19 12:52:43.125697,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-19 12:52:43.126435,RECEIVED,"b'\xbb'"
2026-03-19 12:52:43.127291,RECEIVED,"b'U\x00\xe1h\x03\x01\x0e\xf2Mk'"
2026-03-19 12:52:43.130497,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-19 12:52:43.131124,RECEIVED,"b'\xbb'"
2026-03-19 12:52:43.132227,RECEIVED,"b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'"
2026-03-19 12:52:43.134784,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-19 12:52:43.135455,RECEIVED,"b'\xbb'"
2026-03-19 12:52:43.136261,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-19 12:52:43.141038,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:43.141343,RECEIVED,"b'\xbb'"
2026-03-19 12:52:43.142370,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:44.146667,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:44.147236,RECEIVED,"b'\xbb'"
2026-03-19 12:52:44.148315,RECEIVED,"b'\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:45.160688,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:45.161715,RECEIVED,"b'U'"
2026-03-19 12:52:46.166966,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:46.168249,RECEIVED,"b'U'"
2026-03-19 12:52:47.173747,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:47.174169,RECEIVED,"b'\xbb'"
2026-03-19 12:52:48.179130,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:48.179593,RECEIVED,"b'\xbb'"
2026-03-19 12:52:48.181462,RECEIVED,"b'\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:49.184861,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:49.185219,RECEIVED,"b'\xbb'"
2026-03-19 12:52:49.185898,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:50.188687,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:50.189324,RECEIVED,"b'\xbb'"
2026-03-19 12:52:50.189944,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:51.193924,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:51.194330,RECEIVED,"b'\xbb'"
2026-03-19 12:52:51.195135,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:52.198062,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:52.198732,RECEIVED,"b'\xbb'"
2026-03-19 12:52:52.199484,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:53.203130,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:53.203577,RECEIVED,"b'\xbb'"
2026-03-19 12:52:53.204300,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:54.207989,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:54.208469,RECEIVED,"b'\xbb'"
2026-03-19 12:52:54.209071,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:55.210958,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:55.211257,RECEIVED,"b'\xbb'"
2026-03-19 12:52:55.211822,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:56.213940,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:56.214449,RECEIVED,"b'\xbb'"
2026-03-19 12:52:56.215109,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:57.218519,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:57.219257,RECEIVED,"b'\xbb'"
2026-03-19 12:52:57.219862,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:58.226270,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:58.227078,RECEIVED,"b'\xbb'"
2026-03-19 12:52:58.227755,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:52:59.230747,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:52:59.231662,RECEIVED,"b'\xbb'"
2026-03-19 12:52:59.235276,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:53:00.234070,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:53:00.234623,RECEIVED,"b'\xbb'"
2026-03-19 12:53:00.235221,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:53:01.237701,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:53:01.238012,RECEIVED,"b'\xbb'"
2026-03-19 12:53:01.238538,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-19 12:53:02.240233,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-19 12:53:02.240568,RECEIVED,"b'\xbb'"
2026-03-19 12:53:02.241076,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
1 2026-03-19 12:52:43.093386 SENT b'\xbbU\x00\x03 \x00#I'
2 2026-03-19 12:52:43.094057 RECEIVED b'U'
3 2026-03-19 12:52:43.095431 RECEIVED b'\x00A "\x00\x0f\x00\x00\x00\x00\x00\x00\x9d\x0eDT\x00\x02\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf8'
4 2026-03-19 12:52:43.125697 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
5 2026-03-19 12:52:43.126435 RECEIVED b'\xbb'
6 2026-03-19 12:52:43.127291 RECEIVED b'U\x00\xe1h\x03\x01\x0e\xf2Mk'
7 2026-03-19 12:52:43.130497 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
8 2026-03-19 12:52:43.131124 RECEIVED b'\xbb'
9 2026-03-19 12:52:43.132227 RECEIVED b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'
10 2026-03-19 12:52:43.134784 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
11 2026-03-19 12:52:43.135455 RECEIVED b'\xbb'
12 2026-03-19 12:52:43.136261 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
13 2026-03-19 12:52:43.141038 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
14 2026-03-19 12:52:43.141343 RECEIVED b'\xbb'
15 2026-03-19 12:52:43.142370 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
16 2026-03-19 12:52:44.146667 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
17 2026-03-19 12:52:44.147236 RECEIVED b'\xbb'
18 2026-03-19 12:52:44.148315 RECEIVED b'\x00\xc9h\x03\x01\xf6Ep\xfe'
19 2026-03-19 12:52:45.160688 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
20 2026-03-19 12:52:45.161715 RECEIVED b'U'
21 2026-03-19 12:52:46.166966 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
22 2026-03-19 12:52:46.168249 RECEIVED b'U'
23 2026-03-19 12:52:47.173747 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
24 2026-03-19 12:52:47.174169 RECEIVED b'\xbb'
25 2026-03-19 12:52:48.179130 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
26 2026-03-19 12:52:48.179593 RECEIVED b'\xbb'
27 2026-03-19 12:52:48.181462 RECEIVED b'\x00\xc9h\x03\x01\xf6Ep\xfe'
28 2026-03-19 12:52:49.184861 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
29 2026-03-19 12:52:49.185219 RECEIVED b'\xbb'
30 2026-03-19 12:52:49.185898 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
31 2026-03-19 12:52:50.188687 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
32 2026-03-19 12:52:50.189324 RECEIVED b'\xbb'
33 2026-03-19 12:52:50.189944 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
34 2026-03-19 12:52:51.193924 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
35 2026-03-19 12:52:51.194330 RECEIVED b'\xbb'
36 2026-03-19 12:52:51.195135 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
37 2026-03-19 12:52:52.198062 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
38 2026-03-19 12:52:52.198732 RECEIVED b'\xbb'
39 2026-03-19 12:52:52.199484 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
40 2026-03-19 12:52:53.203130 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
41 2026-03-19 12:52:53.203577 RECEIVED b'\xbb'
42 2026-03-19 12:52:53.204300 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
43 2026-03-19 12:52:54.207989 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
44 2026-03-19 12:52:54.208469 RECEIVED b'\xbb'
45 2026-03-19 12:52:54.209071 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
46 2026-03-19 12:52:55.210958 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
47 2026-03-19 12:52:55.211257 RECEIVED b'\xbb'
48 2026-03-19 12:52:55.211822 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
49 2026-03-19 12:52:56.213940 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
50 2026-03-19 12:52:56.214449 RECEIVED b'\xbb'
51 2026-03-19 12:52:56.215109 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
52 2026-03-19 12:52:57.218519 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
53 2026-03-19 12:52:57.219257 RECEIVED b'\xbb'
54 2026-03-19 12:52:57.219862 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
55 2026-03-19 12:52:58.226270 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
56 2026-03-19 12:52:58.227078 RECEIVED b'\xbb'
57 2026-03-19 12:52:58.227755 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
58 2026-03-19 12:52:59.230747 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
59 2026-03-19 12:52:59.231662 RECEIVED b'\xbb'
60 2026-03-19 12:52:59.235276 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
61 2026-03-19 12:53:00.234070 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
62 2026-03-19 12:53:00.234623 RECEIVED b'\xbb'
63 2026-03-19 12:53:00.235221 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
64 2026-03-19 12:53:01.237701 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
65 2026-03-19 12:53:01.238012 RECEIVED b'\xbb'
66 2026-03-19 12:53:01.238538 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
67 2026-03-19 12:53:02.240233 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
68 2026-03-19 12:53:02.240568 RECEIVED b'\xbb'
69 2026-03-19 12:53:02.241076 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'

View File

@@ -0,0 +1,17 @@
2026-03-19 12:52:43.085 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-19_12-52-42_log_usv.log.
2026-03-19 12:52:43.086 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-19 12:52:43.087 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-19_12-52-42_AUV_usbl.csv
2026-03-19 12:52:43.089 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-19 12:52:43.090 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-19 12:52:43.114 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-19 12:52:43.128 | INFO | __main__:main:127 - set_auto_response_filter(0)=True
2026-03-19 12:52:43.133 | INFO | __main__:main:129 - set_auto_response_timeout(0xffffffff)=True
2026-03-19 12:52:43.137 | INFO | __main__:main:131 - set_auto_response_payload(0xff)=True
2026-03-19 12:52:44.167 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-19 12:52:45.181 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-19 12:52:46.187 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-19 12:52:47.194 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-19 12:52:48.199 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-19 12:53:02.544 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-19 12:53:02.545 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-19 12:53:02.546 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,171 @@
2026-03-20 13:29:40.685622,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 13:29:40.686113,RECEIVED,"b'\xbb'"
2026-03-20 13:29:40.686631,RECEIVED,"b'U\x00A ""\x00\x0f\x00\x00\x00\x00\x00\x00\xa4\xdeX\xcb\x00\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xc7'"
2026-03-20 13:29:40.697732,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 13:29:40.698036,RECEIVED,"b'\xbb'"
2026-03-20 13:29:40.698530,RECEIVED,"b'U\x00\xe1h\x03\x01\x0e\xf2Mk'"
2026-03-20 13:29:40.699549,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 13:29:40.700153,RECEIVED,"b'\xbb'"
2026-03-20 13:29:40.700901,RECEIVED,"b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'"
2026-03-20 13:29:40.702460,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-20 13:29:40.702795,RECEIVED,"b'\xbb'"
2026-03-20 13:29:40.703348,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-20 13:29:40.705177,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 13:29:40.705467,RECEIVED,"b'\xbb'"
2026-03-20 13:29:40.705933,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 13:29:41.707772,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 13:29:41.708136,RECEIVED,"b'\xbb'"
2026-03-20 13:29:41.708629,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 13:29:42.710038,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 13:29:42.710418,RECEIVED,"b'\xbb'"
2026-03-20 13:29:42.710945,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 13:29:43.712949,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 13:29:43.713285,RECEIVED,"b'\xbb'"
2026-03-20 13:29:43.713788,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 13:29:44.716604,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:44.717163,RECEIVED,"b'\xbb'"
2026-03-20 13:29:44.717754,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:45.719019,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:45.719331,RECEIVED,"b'\xbb'"
2026-03-20 13:29:45.719787,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:46.721761,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:46.722218,RECEIVED,"b'\xbb'"
2026-03-20 13:29:46.722973,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:47.724551,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:47.725083,RECEIVED,"b'\xbb'"
2026-03-20 13:29:47.725589,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:48.726724,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:48.727124,RECEIVED,"b'\xbb'"
2026-03-20 13:29:48.727642,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:49.729311,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:49.729972,RECEIVED,"b'\xbb'"
2026-03-20 13:29:49.730481,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:50.732974,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:50.733321,RECEIVED,"b'\xbb'"
2026-03-20 13:29:50.745741,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:51.735340,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:51.735698,RECEIVED,"b'\xbb'"
2026-03-20 13:29:51.736201,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:52.737902,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:52.738444,RECEIVED,"b'\xbb'"
2026-03-20 13:29:52.738981,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:53.740506,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:53.741278,RECEIVED,"b'\xbb'"
2026-03-20 13:29:53.741774,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:54.743950,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:54.744286,RECEIVED,"b'\xbb'"
2026-03-20 13:29:54.744782,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:55.746302,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:55.746747,RECEIVED,"b'\xbb'"
2026-03-20 13:29:55.752265,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:56.748667,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:56.749048,RECEIVED,"b'\xbb'"
2026-03-20 13:29:56.749546,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:57.752107,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:57.752642,RECEIVED,"b'\xbb'"
2026-03-20 13:29:57.753174,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:58.754402,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:58.754769,RECEIVED,"b'\xbb'"
2026-03-20 13:29:58.755267,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:29:59.756942,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:29:59.757496,RECEIVED,"b'\xbb'"
2026-03-20 13:29:59.758021,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:00.759423,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:00.759968,RECEIVED,"b'\xbb'"
2026-03-20 13:30:00.764284,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:01.762172,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:01.762762,RECEIVED,"b'\xbb'"
2026-03-20 13:30:01.763307,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:02.764335,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:02.764668,RECEIVED,"b'\xbb'"
2026-03-20 13:30:02.765179,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:03.767188,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:03.767518,RECEIVED,"b'\xbb'"
2026-03-20 13:30:03.768034,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:04.770094,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:04.770493,RECEIVED,"b'\xbb'"
2026-03-20 13:30:04.771154,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:05.773078,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:05.773608,RECEIVED,"b'\xbb'"
2026-03-20 13:30:05.774126,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:06.775738,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:06.776200,RECEIVED,"b'\xbb'"
2026-03-20 13:30:06.776696,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:07.778103,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:07.778635,RECEIVED,"b'\xbb'"
2026-03-20 13:30:07.779151,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:08.780532,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:08.781126,RECEIVED,"b'\xbb'"
2026-03-20 13:30:08.781632,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:09.783211,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:09.783757,RECEIVED,"b'\xbb'"
2026-03-20 13:30:09.784256,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:10.785543,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:10.786107,RECEIVED,"b'\xbb'"
2026-03-20 13:30:10.786639,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:11.788390,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:11.789317,RECEIVED,"b'\xbb'"
2026-03-20 13:30:11.789855,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:12.790970,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:12.791292,RECEIVED,"b'\xbb'"
2026-03-20 13:30:12.791782,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:13.793085,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:13.793639,RECEIVED,"b'\xbb'"
2026-03-20 13:30:13.794168,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:14.795325,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:14.795862,RECEIVED,"b'\xbb'"
2026-03-20 13:30:14.796378,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:15.798342,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:15.798981,RECEIVED,"b'\xbb'"
2026-03-20 13:30:15.799565,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:16.802200,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:16.802991,RECEIVED,"b'\xbb'"
2026-03-20 13:30:16.803606,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:17.804806,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:17.805175,RECEIVED,"b'\xbb'"
2026-03-20 13:30:17.805710,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:18.807125,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:18.807735,RECEIVED,"b'\xbb'"
2026-03-20 13:30:18.808259,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:19.809658,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:19.810065,RECEIVED,"b'\xbb'"
2026-03-20 13:30:19.810613,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:20.812778,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:20.813465,RECEIVED,"b'\xbb'"
2026-03-20 13:30:20.814135,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:21.815928,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:21.816587,RECEIVED,"b'\xbb'"
2026-03-20 13:30:21.817199,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:22.819069,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:22.819606,RECEIVED,"b'\xbb'"
2026-03-20 13:30:22.820110,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:23.821592,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:23.823013,RECEIVED,"b'\xbb'"
2026-03-20 13:30:23.823554,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:24.824027,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:24.824404,RECEIVED,"b'\xbb'"
2026-03-20 13:30:24.824900,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:25.826202,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:25.826795,RECEIVED,"b'\xbb'"
2026-03-20 13:30:25.827323,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:26.828607,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:26.829128,RECEIVED,"b'\xbb'"
2026-03-20 13:30:26.829628,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:27.830915,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:27.831230,RECEIVED,"b'\xbb'"
2026-03-20 13:30:27.831752,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:28.833564,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:28.834096,RECEIVED,"b'\xbb'"
2026-03-20 13:30:28.834595,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:29.836626,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:29.837565,RECEIVED,"b'\xbb'"
2026-03-20 13:30:29.838242,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:30.839058,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:30.839598,RECEIVED,"b'\xbb'"
2026-03-20 13:30:30.840193,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:31.842311,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:31.842829,RECEIVED,"b'\xbb'"
2026-03-20 13:30:31.843374,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 13:30:32.844556,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 13:30:32.845112,RECEIVED,"b'\xbb'"
2026-03-20 13:30:32.845615,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
1 2026-03-20 13:29:40.685622 SENT b'\xbbU\x00\x03 \x00#I'
2 2026-03-20 13:29:40.686113 RECEIVED b'\xbb'
3 2026-03-20 13:29:40.686631 RECEIVED b'U\x00A "\x00\x0f\x00\x00\x00\x00\x00\x00\xa4\xdeX\xcb\x00\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xc7'
4 2026-03-20 13:29:40.697732 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
5 2026-03-20 13:29:40.698036 RECEIVED b'\xbb'
6 2026-03-20 13:29:40.698530 RECEIVED b'U\x00\xe1h\x03\x01\x0e\xf2Mk'
7 2026-03-20 13:29:40.699549 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
8 2026-03-20 13:29:40.700153 RECEIVED b'\xbb'
9 2026-03-20 13:29:40.700901 RECEIVED b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'
10 2026-03-20 13:29:40.702460 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
11 2026-03-20 13:29:40.702795 RECEIVED b'\xbb'
12 2026-03-20 13:29:40.703348 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
13 2026-03-20 13:29:40.705177 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
14 2026-03-20 13:29:40.705467 RECEIVED b'\xbb'
15 2026-03-20 13:29:40.705933 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
16 2026-03-20 13:29:41.707772 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
17 2026-03-20 13:29:41.708136 RECEIVED b'\xbb'
18 2026-03-20 13:29:41.708629 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
19 2026-03-20 13:29:42.710038 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
20 2026-03-20 13:29:42.710418 RECEIVED b'\xbb'
21 2026-03-20 13:29:42.710945 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
22 2026-03-20 13:29:43.712949 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
23 2026-03-20 13:29:43.713285 RECEIVED b'\xbb'
24 2026-03-20 13:29:43.713788 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
25 2026-03-20 13:29:44.716604 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
26 2026-03-20 13:29:44.717163 RECEIVED b'\xbb'
27 2026-03-20 13:29:44.717754 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
28 2026-03-20 13:29:45.719019 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
29 2026-03-20 13:29:45.719331 RECEIVED b'\xbb'
30 2026-03-20 13:29:45.719787 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
31 2026-03-20 13:29:46.721761 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
32 2026-03-20 13:29:46.722218 RECEIVED b'\xbb'
33 2026-03-20 13:29:46.722973 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
34 2026-03-20 13:29:47.724551 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
35 2026-03-20 13:29:47.725083 RECEIVED b'\xbb'
36 2026-03-20 13:29:47.725589 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
37 2026-03-20 13:29:48.726724 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
38 2026-03-20 13:29:48.727124 RECEIVED b'\xbb'
39 2026-03-20 13:29:48.727642 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
40 2026-03-20 13:29:49.729311 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
41 2026-03-20 13:29:49.729972 RECEIVED b'\xbb'
42 2026-03-20 13:29:49.730481 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
43 2026-03-20 13:29:50.732974 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
44 2026-03-20 13:29:50.733321 RECEIVED b'\xbb'
45 2026-03-20 13:29:50.745741 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
46 2026-03-20 13:29:51.735340 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
47 2026-03-20 13:29:51.735698 RECEIVED b'\xbb'
48 2026-03-20 13:29:51.736201 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
49 2026-03-20 13:29:52.737902 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
50 2026-03-20 13:29:52.738444 RECEIVED b'\xbb'
51 2026-03-20 13:29:52.738981 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
52 2026-03-20 13:29:53.740506 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
53 2026-03-20 13:29:53.741278 RECEIVED b'\xbb'
54 2026-03-20 13:29:53.741774 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
55 2026-03-20 13:29:54.743950 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
56 2026-03-20 13:29:54.744286 RECEIVED b'\xbb'
57 2026-03-20 13:29:54.744782 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
58 2026-03-20 13:29:55.746302 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
59 2026-03-20 13:29:55.746747 RECEIVED b'\xbb'
60 2026-03-20 13:29:55.752265 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
61 2026-03-20 13:29:56.748667 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
62 2026-03-20 13:29:56.749048 RECEIVED b'\xbb'
63 2026-03-20 13:29:56.749546 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
64 2026-03-20 13:29:57.752107 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
65 2026-03-20 13:29:57.752642 RECEIVED b'\xbb'
66 2026-03-20 13:29:57.753174 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
67 2026-03-20 13:29:58.754402 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
68 2026-03-20 13:29:58.754769 RECEIVED b'\xbb'
69 2026-03-20 13:29:58.755267 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
70 2026-03-20 13:29:59.756942 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
71 2026-03-20 13:29:59.757496 RECEIVED b'\xbb'
72 2026-03-20 13:29:59.758021 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
73 2026-03-20 13:30:00.759423 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
74 2026-03-20 13:30:00.759968 RECEIVED b'\xbb'
75 2026-03-20 13:30:00.764284 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
76 2026-03-20 13:30:01.762172 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
77 2026-03-20 13:30:01.762762 RECEIVED b'\xbb'
78 2026-03-20 13:30:01.763307 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
79 2026-03-20 13:30:02.764335 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
80 2026-03-20 13:30:02.764668 RECEIVED b'\xbb'
81 2026-03-20 13:30:02.765179 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
82 2026-03-20 13:30:03.767188 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
83 2026-03-20 13:30:03.767518 RECEIVED b'\xbb'
84 2026-03-20 13:30:03.768034 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
85 2026-03-20 13:30:04.770094 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
86 2026-03-20 13:30:04.770493 RECEIVED b'\xbb'
87 2026-03-20 13:30:04.771154 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
88 2026-03-20 13:30:05.773078 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
89 2026-03-20 13:30:05.773608 RECEIVED b'\xbb'
90 2026-03-20 13:30:05.774126 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
91 2026-03-20 13:30:06.775738 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
92 2026-03-20 13:30:06.776200 RECEIVED b'\xbb'
93 2026-03-20 13:30:06.776696 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
94 2026-03-20 13:30:07.778103 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
95 2026-03-20 13:30:07.778635 RECEIVED b'\xbb'
96 2026-03-20 13:30:07.779151 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
97 2026-03-20 13:30:08.780532 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
98 2026-03-20 13:30:08.781126 RECEIVED b'\xbb'
99 2026-03-20 13:30:08.781632 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
100 2026-03-20 13:30:09.783211 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
101 2026-03-20 13:30:09.783757 RECEIVED b'\xbb'
102 2026-03-20 13:30:09.784256 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
103 2026-03-20 13:30:10.785543 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
104 2026-03-20 13:30:10.786107 RECEIVED b'\xbb'
105 2026-03-20 13:30:10.786639 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
106 2026-03-20 13:30:11.788390 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
107 2026-03-20 13:30:11.789317 RECEIVED b'\xbb'
108 2026-03-20 13:30:11.789855 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
109 2026-03-20 13:30:12.790970 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
110 2026-03-20 13:30:12.791292 RECEIVED b'\xbb'
111 2026-03-20 13:30:12.791782 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
112 2026-03-20 13:30:13.793085 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
113 2026-03-20 13:30:13.793639 RECEIVED b'\xbb'
114 2026-03-20 13:30:13.794168 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
115 2026-03-20 13:30:14.795325 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
116 2026-03-20 13:30:14.795862 RECEIVED b'\xbb'
117 2026-03-20 13:30:14.796378 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
118 2026-03-20 13:30:15.798342 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
119 2026-03-20 13:30:15.798981 RECEIVED b'\xbb'
120 2026-03-20 13:30:15.799565 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
121 2026-03-20 13:30:16.802200 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
122 2026-03-20 13:30:16.802991 RECEIVED b'\xbb'
123 2026-03-20 13:30:16.803606 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
124 2026-03-20 13:30:17.804806 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
125 2026-03-20 13:30:17.805175 RECEIVED b'\xbb'
126 2026-03-20 13:30:17.805710 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
127 2026-03-20 13:30:18.807125 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
128 2026-03-20 13:30:18.807735 RECEIVED b'\xbb'
129 2026-03-20 13:30:18.808259 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
130 2026-03-20 13:30:19.809658 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
131 2026-03-20 13:30:19.810065 RECEIVED b'\xbb'
132 2026-03-20 13:30:19.810613 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
133 2026-03-20 13:30:20.812778 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
134 2026-03-20 13:30:20.813465 RECEIVED b'\xbb'
135 2026-03-20 13:30:20.814135 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
136 2026-03-20 13:30:21.815928 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
137 2026-03-20 13:30:21.816587 RECEIVED b'\xbb'
138 2026-03-20 13:30:21.817199 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
139 2026-03-20 13:30:22.819069 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
140 2026-03-20 13:30:22.819606 RECEIVED b'\xbb'
141 2026-03-20 13:30:22.820110 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
142 2026-03-20 13:30:23.821592 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
143 2026-03-20 13:30:23.823013 RECEIVED b'\xbb'
144 2026-03-20 13:30:23.823554 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
145 2026-03-20 13:30:24.824027 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
146 2026-03-20 13:30:24.824404 RECEIVED b'\xbb'
147 2026-03-20 13:30:24.824900 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
148 2026-03-20 13:30:25.826202 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
149 2026-03-20 13:30:25.826795 RECEIVED b'\xbb'
150 2026-03-20 13:30:25.827323 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
151 2026-03-20 13:30:26.828607 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
152 2026-03-20 13:30:26.829128 RECEIVED b'\xbb'
153 2026-03-20 13:30:26.829628 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
154 2026-03-20 13:30:27.830915 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
155 2026-03-20 13:30:27.831230 RECEIVED b'\xbb'
156 2026-03-20 13:30:27.831752 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
157 2026-03-20 13:30:28.833564 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
158 2026-03-20 13:30:28.834096 RECEIVED b'\xbb'
159 2026-03-20 13:30:28.834595 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
160 2026-03-20 13:30:29.836626 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
161 2026-03-20 13:30:29.837565 RECEIVED b'\xbb'
162 2026-03-20 13:30:29.838242 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
163 2026-03-20 13:30:30.839058 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
164 2026-03-20 13:30:30.839598 RECEIVED b'\xbb'
165 2026-03-20 13:30:30.840193 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
166 2026-03-20 13:30:31.842311 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
167 2026-03-20 13:30:31.842829 RECEIVED b'\xbb'
168 2026-03-20 13:30:31.843374 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
169 2026-03-20 13:30:32.844556 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
170 2026-03-20 13:30:32.845112 RECEIVED b'\xbb'
171 2026-03-20 13:30:32.845615 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'

View File

@@ -0,0 +1,11 @@
2026-03-20 13:29:40.681 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_13-29-40_log_usv.log.
2026-03-20 13:29:40.682 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 13:29:40.683 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_13-29-40_AUV_usbl.csv
2026-03-20 13:29:40.684 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 13:29:40.684 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 13:29:40.699 | INFO | __main__:main:127 - set_auto_response_filter(0)=True
2026-03-20 13:29:40.701 | INFO | __main__:main:129 - set_auto_response_timeout(0xffffffff)=True
2026-03-20 13:29:40.703 | INFO | __main__:main:131 - set_auto_response_payload(0xff)=True
2026-03-20 13:30:33.550 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 13:30:33.552 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 13:30:33.552 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,5 @@
2026-03-20 13:35:32.057 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_13-35-32_log_auv.log.
2026-03-20 13:35:32.057 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0, baudrate 921600, address 0
2026-03-20 13:35:32.058 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_13-35-32_AUV_usbl.csv
2026-03-20 13:35:32.058 | ERROR | kogger_protocol_driver:connect:317 - Error connecting to /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0: [Errno 2] could not open port /dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0: [Errno 2] No such file or directory: '/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0'
2026-03-20 13:35:32.059 | WARNING | kogger_protocol_driver:disconnect:341 - Not connected or already disconnected.

View File

@@ -0,0 +1,81 @@
2026-03-20 13:35:54.062535,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 13:35:54.093789,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 13:35:54.094104,RECEIVED,"b'\xbb'"
2026-03-20 13:35:54.094674,RECEIVED,"b'U\x00A ""\x00\x0f\x00\x00\x00\x00\x00\x00\xa4\xdeX\xcb\x00\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xc7'"
2026-03-20 13:35:54.105845,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 13:35:54.106104,RECEIVED,"b'\xbb'"
2026-03-20 13:35:54.106595,RECEIVED,"b'U\x00A!\x01\x00ci'"
2026-03-20 13:35:54.117558,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 13:35:54.148832,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 13:35:54.149126,RECEIVED,"b'\xbb'"
2026-03-20 13:35:54.149675,RECEIVED,"b'U\x00\xe1h\x03\x01\x0e\xf2Mk'"
2026-03-20 13:35:54.151330,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 13:35:54.152194,RECEIVED,"b'\xbb'"
2026-03-20 13:35:54.152954,RECEIVED,"b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'"
2026-03-20 13:35:54.154269,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-20 13:35:54.154500,RECEIVED,"b'\xbb'"
2026-03-20 13:35:54.155038,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-20 13:35:59.189642,RECEIVED,"b'\xbb'"
2026-03-20 13:35:59.190610,RECEIVED,"b'U\x00Ae\x98\x03\x00\x00\x00\xb5\xb458\x00\x00\x00\x00\x00\x00\x00\x00B\xa6\xaf\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x00\x00\xb6B\x00\x00\x00\x0033\x8a\xc2\x00\x00\x00\x00\xfe\xe6\x8aA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xac\xfb\x98\xc2WAa\xc1\x15K'"
2026-03-20 13:35:59.191222,RECEIVED,"b'-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f""\xf2'"
2026-03-20 13:36:00.159731,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-20 13:36:00.160188,RECEIVED,"b'\xbb'"
2026-03-20 13:36:00.160709,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-20 13:36:03.182896,RECEIVED,"b'\xbb'"
2026-03-20 13:36:03.183435,RECEIVED,"b'U\x00Ae\x98\x04\x00\x00\x00r\xa3r8\x00\x00\x00\x00\x00\x00\x00\x00\x9b|\xb1\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00f\xe6\x1b\xc3\x00\x00\x00\x0043\x83\xc1\x00\x00\x00\x00\x84\xf6\x88A\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:03.183903,RECEIVED,"b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xc2\x1c\x9d\xc2\x18\xc1Y\xc1\xcc\xdf.\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:03.184392,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:03.184851,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xbd('"
2026-03-20 13:36:19.222085,RECEIVED,"b'\xbb'"
2026-03-20 13:36:19.222666,RECEIVED,"b'U\x00Ae\x98\x01\x00\x00\x00\xccfg9\x00\x00\x00\x00\x00\x00\x00\x00A\xd5\xb8\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xcd\xcc/\xc3\x00\x00\x00\x00\xff\xffCB\x00\x00\x00\x00\x8b\xe7\xa9A\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:19.223147,RECEIVED,"b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00`\xe1\xad\xc2d g\xc1\xe8\xcf+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:19.223606,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fZ\xf7'"
2026-03-20 13:36:20.248037,RECEIVED,"b'\xbb'"
2026-03-20 13:36:20.248606,RECEIVED,"b'U\x00Ae\x98\x04\x00\x00\x00[\x0ew9\x00\x00\x00\x00\x00\x00\x00\x00\xc1J\xb9\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x00\x00*\xc3\x00\x00\x00\x00ef0B\x00\x00\x00\x00\xc9\x87\x9eA\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:20.249080,RECEIVED,"b""\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xa9-\xad\xc2\xd1HW\xc1\x05',\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"""
2026-03-20 13:36:20.249590,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x19]'"
2026-03-20 13:36:21.238002,RECEIVED,"b'\xbb'"
2026-03-20 13:36:21.238660,RECEIVED,"b'U\x00Ae\x98\x05\x00\x00\x00\x95)\x869\x00\x00\x00\x00\x00\x00\x00\x00L\xc0\xb9\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x00\x80)\xc3\x00\x00\x00\x00efJB\x00\x00\x00\x00\xd2\xf7\xa1A\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:21.239190,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x005\x02\xab\xc2\x03\xc4k\xc1\x86N-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'"
2026-03-20 13:36:21.239659,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f^\xa0'"
2026-03-20 13:36:22.227912,RECEIVED,"b'\xbb'"
2026-03-20 13:36:22.228483,RECEIVED,"b'U\x00Ae\x98\x05\x00\x00\x00\xb4D\x959\x00\x00\x00\x00\x00\x00\x00\x00\xcd5\xba\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x005\xb3,\xc3\x00\x00\x00\x00\xcb\xccDB\x00\x00\x00\x00\x0e \xaeA\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:22.228959,RECEIVED,"b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x17\x9b\xab\xc2\xd3x~\xc1\x14\xce,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:22.229490,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f`\xa1'"
2026-03-20 13:36:23.251746,RECEIVED,"b'\xbb'"
2026-03-20 13:36:23.252436,RECEIVED,"b""U\x00Ae\x98\x05\x00\x00\x00\x1c\xe1\xa49\x00\x00\x00\x00\x00\x00\x00\x00N\xab\xba\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xceL'\xc3\x00\x00\x00\x00\xfe\xff=B\x00\x00\x00\x00s\x02\x9eA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"""
2026-03-20 13:36:23.252980,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00;D\xab\xc2f\\J\xc1\xa6\xd8+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'"
2026-03-20 13:36:23.253531,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xd9\xc9'"
2026-03-20 13:36:24.241702,RECEIVED,"b'\xbb'"
2026-03-20 13:36:24.242474,RECEIVED,"b'U\x00Ae\x98\x06\x00\x00\x00I\xfc\xb39\x00\x00\x00\x00\x00\x00\x00\x00\xd8 \xbb\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00432\xc3\x00\x00\x00\x00ff2B\x00\x00\x00\x00\x86\x8b\xaaA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:24.243066,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00L\xaf\xaa\xc2S\x08\x85\xc1\n\xe7-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:24.243548,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xb9\xd8'"
2026-03-20 13:36:25.263660,RECEIVED,"b'\xbb'"
2026-03-20 13:36:25.264421,RECEIVED,"b'U\x00Ae\x98\x05\x00\x00\x00z\x98\xc39\x00\x00\x00\x00\x00\x00\x00\x00d\x96\xbb\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x9b\x99-\xc3\x00\x00\x00\x00\x98\x995B\x00\x00\x00\x00\x93/\x9cA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8'"
2026-03-20 13:36:25.265012,RECEIVED,"b'\x7f\x00\x00\x00\x00n\xeb\xab\xc2\xb8\xb1F\xc1\xc1\x12,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0'"
2026-03-20 13:36:25.265532,RECEIVED,"b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fy\x9f'"
2026-03-20 13:36:26.176979,SENT,"b'\xbbU\x00\xaah\x01\x05\x18\xe7'"
2026-03-20 13:36:26.177475,RECEIVED,"b'\xbb'"
2026-03-20 13:36:26.177969,RECEIVED,"b'U\x00\xe9h\x03\x01\x18\xe7T\xa4'"
2026-03-20 13:36:26.253913,RECEIVED,"b'\xbb'"
2026-03-20 13:36:26.254833,RECEIVED,"b'U\x00Ae\x98\x05\x00\x00\x00\x96\xb3\xd29\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0b\xbc\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xceL\x1d\xc3\x00\x00\x00\x00\x97\x99mB\x00\x00\x00\x00\xc0\x0b\xa3A\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xc4\xec\xaa\xc2\x16pi\xc1\xb47'"
2026-03-20 13:36:26.255563,RECEIVED,"b'-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x97\xff'"
2026-03-20 13:36:27.243846,RECEIVED,"b'\xbb'"
2026-03-20 13:36:27.244622,RECEIVED,"b'U\x00Ae\x98\x06\x00\x00\x00\xc0\xce\xe19\x00\x00\x00\x00\x00\x00\x00\x00\x92\x81\xbc\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xcd\xcc/\xc3\x00\x00\x00\x00\xcb\xccNB\x00\x00\x00\x00\xc2k\xa5A\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:27.245273,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00q\x88\xaa\xc24os\xc1F0,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:27.245761,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f1\xc1'"
2026-03-20 13:36:28.269778,RECEIVED,"b'\xbb'"
2026-03-20 13:36:28.270363,RECEIVED,"b'U\x00Ae\x98\x05\x00\x00\x00Zv\xf19\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf7\xbc\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00gf2\xc3\x00\x00\x00\x00\xcb\xccRB\x00\x00\x00\x00YH\x99A\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:28.270947,RECEIVED,"b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00p=\xaa\xc2\xbe\xb6_\xc1\\4-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'"
2026-03-20 13:36:28.271457,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xb4\x00'"
2026-03-20 13:36:29.259732,RECEIVED,"b'\xbb'"
2026-03-20 13:36:29.260337,RECEIVED,"b""U\x00Ae\x98\x04\x00\x00\x00i\x91\x00:\x00\x00\x00\x00\x00\x00\x00\x00\xa3l\xbd\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x9a\x19'\xc3\x00\x00\x00\x00\xfe\xff{B\x00\x00\x00\x00\x04\x91\xa8A\x00\x00\xc0\x7f\x00\x00"""
2026-03-20 13:36:29.260921,RECEIVED,"b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00-<\xaa\xc2\xddhu\xc1Y\x8e+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'"
2026-03-20 13:36:29.261362,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fL='"
2026-03-20 13:36:30.283273,RECEIVED,"b'\xbb'"
2026-03-20 13:36:30.283980,RECEIVED,"b'U\x00Ae\x98\x06\x00\x00\x00\xea-\x10:\x00\x00\x00\x00\x00\x00\x00\x00%\xe2\xbd\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00433\xc3\x00\x00\x00\x00\xcc\xcc*B\x00\x00\x00\x00\x0b7\x8bA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-20 13:36:30.284828,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00F\xa1\xa9\xc2@5_\xc1\xd3\xf5,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x869'"
2026-03-20 13:36:31.273220,RECEIVED,"b'\xbb'"
2026-03-20 13:36:31.273794,RECEIVED,"b'U\x00Ae\x98\x00\x00\x00\x00\x08I\x1f:\x00\x00\x00\x00\x00\x00\x00\x00\xb0W\xbe\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x98\x99\xddA\x00\x00\x00\x00\x9a\x99\xe6\xc2\x00\x00\x00\x009\xcc\x92A\x00\x00\xc0\x7f\x00\x00'"
2026-03-20 13:36:31.274340,RECEIVED,"b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x82\x95\xa9\xc25\xaf`\xc1\xd2\xf0+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'"
2026-03-20 13:36:31.274867,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xf6\xbf'"
1 2026-03-20 13:35:54.062535 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 13:35:54.093789 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 13:35:54.094104 RECEIVED b'\xbb'
4 2026-03-20 13:35:54.094674 RECEIVED b'U\x00A "\x00\x0f\x00\x00\x00\x00\x00\x00\xa4\xdeX\xcb\x00\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xc7'
5 2026-03-20 13:35:54.105845 SENT b'\xbbU\x00\x03!\x00$K'
6 2026-03-20 13:35:54.106104 RECEIVED b'\xbb'
7 2026-03-20 13:35:54.106595 RECEIVED b'U\x00A!\x01\x00ci'
8 2026-03-20 13:35:54.117558 SENT b'\xbbU\x00\x03e\x00h\xd3'
9 2026-03-20 13:35:54.148832 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
10 2026-03-20 13:35:54.149126 RECEIVED b'\xbb'
11 2026-03-20 13:35:54.149675 RECEIVED b'U\x00\xe1h\x03\x01\x0e\xf2Mk'
12 2026-03-20 13:35:54.151330 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
13 2026-03-20 13:35:54.152194 RECEIVED b'\xbb'
14 2026-03-20 13:35:54.152954 RECEIVED b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'
15 2026-03-20 13:35:54.154269 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
16 2026-03-20 13:35:54.154500 RECEIVED b'\xbb'
17 2026-03-20 13:35:54.155038 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
18 2026-03-20 13:35:59.189642 RECEIVED b'\xbb'
19 2026-03-20 13:35:59.190610 RECEIVED b'U\x00Ae\x98\x03\x00\x00\x00\xb5\xb458\x00\x00\x00\x00\x00\x00\x00\x00B\xa6\xaf\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x00\x00\xb6B\x00\x00\x00\x0033\x8a\xc2\x00\x00\x00\x00\xfe\xe6\x8aA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xac\xfb\x98\xc2WAa\xc1\x15K'
20 2026-03-20 13:35:59.191222 RECEIVED b'-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f"\xf2'
21 2026-03-20 13:36:00.159731 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
22 2026-03-20 13:36:00.160188 RECEIVED b'\xbb'
23 2026-03-20 13:36:00.160709 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
24 2026-03-20 13:36:03.182896 RECEIVED b'\xbb'
25 2026-03-20 13:36:03.183435 RECEIVED b'U\x00Ae\x98\x04\x00\x00\x00r\xa3r8\x00\x00\x00\x00\x00\x00\x00\x00\x9b|\xb1\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00f\xe6\x1b\xc3\x00\x00\x00\x0043\x83\xc1\x00\x00\x00\x00\x84\xf6\x88A\x00\x00\xc0\x7f\x00\x00'
26 2026-03-20 13:36:03.183903 RECEIVED b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xc2\x1c\x9d\xc2\x18\xc1Y\xc1\xcc\xdf.\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
27 2026-03-20 13:36:03.184392 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'
28 2026-03-20 13:36:03.184851 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xbd('
29 2026-03-20 13:36:19.222085 RECEIVED b'\xbb'
30 2026-03-20 13:36:19.222666 RECEIVED b'U\x00Ae\x98\x01\x00\x00\x00\xccfg9\x00\x00\x00\x00\x00\x00\x00\x00A\xd5\xb8\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xcd\xcc/\xc3\x00\x00\x00\x00\xff\xffCB\x00\x00\x00\x00\x8b\xe7\xa9A\x00\x00\xc0\x7f\x00\x00'
31 2026-03-20 13:36:19.223147 RECEIVED b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00`\xe1\xad\xc2d g\xc1\xe8\xcf+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
32 2026-03-20 13:36:19.223606 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fZ\xf7'
33 2026-03-20 13:36:20.248037 RECEIVED b'\xbb'
34 2026-03-20 13:36:20.248606 RECEIVED b'U\x00Ae\x98\x04\x00\x00\x00[\x0ew9\x00\x00\x00\x00\x00\x00\x00\x00\xc1J\xb9\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x00\x00*\xc3\x00\x00\x00\x00ef0B\x00\x00\x00\x00\xc9\x87\x9eA\x00\x00\xc0\x7f\x00\x00'
35 2026-03-20 13:36:20.249080 RECEIVED b"\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xa9-\xad\xc2\xd1HW\xc1\x05',\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"
36 2026-03-20 13:36:20.249590 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x19]'
37 2026-03-20 13:36:21.238002 RECEIVED b'\xbb'
38 2026-03-20 13:36:21.238660 RECEIVED b'U\x00Ae\x98\x05\x00\x00\x00\x95)\x869\x00\x00\x00\x00\x00\x00\x00\x00L\xc0\xb9\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x00\x80)\xc3\x00\x00\x00\x00efJB\x00\x00\x00\x00\xd2\xf7\xa1A\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
39 2026-03-20 13:36:21.239190 RECEIVED b'\xf8\x7f\x00\x00\x00\x005\x02\xab\xc2\x03\xc4k\xc1\x86N-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'
40 2026-03-20 13:36:21.239659 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f^\xa0'
41 2026-03-20 13:36:22.227912 RECEIVED b'\xbb'
42 2026-03-20 13:36:22.228483 RECEIVED b'U\x00Ae\x98\x05\x00\x00\x00\xb4D\x959\x00\x00\x00\x00\x00\x00\x00\x00\xcd5\xba\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x005\xb3,\xc3\x00\x00\x00\x00\xcb\xccDB\x00\x00\x00\x00\x0e \xaeA\x00\x00\xc0\x7f\x00\x00'
43 2026-03-20 13:36:22.228959 RECEIVED b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x17\x9b\xab\xc2\xd3x~\xc1\x14\xce,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
44 2026-03-20 13:36:22.229490 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f`\xa1'
45 2026-03-20 13:36:23.251746 RECEIVED b'\xbb'
46 2026-03-20 13:36:23.252436 RECEIVED b"U\x00Ae\x98\x05\x00\x00\x00\x1c\xe1\xa49\x00\x00\x00\x00\x00\x00\x00\x00N\xab\xba\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xceL'\xc3\x00\x00\x00\x00\xfe\xff=B\x00\x00\x00\x00s\x02\x9eA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"
47 2026-03-20 13:36:23.252980 RECEIVED b'\xf8\x7f\x00\x00\x00\x00;D\xab\xc2f\\J\xc1\xa6\xd8+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'
48 2026-03-20 13:36:23.253531 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xd9\xc9'
49 2026-03-20 13:36:24.241702 RECEIVED b'\xbb'
50 2026-03-20 13:36:24.242474 RECEIVED b'U\x00Ae\x98\x06\x00\x00\x00I\xfc\xb39\x00\x00\x00\x00\x00\x00\x00\x00\xd8 \xbb\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00432\xc3\x00\x00\x00\x00ff2B\x00\x00\x00\x00\x86\x8b\xaaA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
51 2026-03-20 13:36:24.243066 RECEIVED b'\xf8\x7f\x00\x00\x00\x00L\xaf\xaa\xc2S\x08\x85\xc1\n\xe7-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'
52 2026-03-20 13:36:24.243548 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xb9\xd8'
53 2026-03-20 13:36:25.263660 RECEIVED b'\xbb'
54 2026-03-20 13:36:25.264421 RECEIVED b'U\x00Ae\x98\x05\x00\x00\x00z\x98\xc39\x00\x00\x00\x00\x00\x00\x00\x00d\x96\xbb\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x9b\x99-\xc3\x00\x00\x00\x00\x98\x995B\x00\x00\x00\x00\x93/\x9cA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8'
55 2026-03-20 13:36:25.265012 RECEIVED b'\x7f\x00\x00\x00\x00n\xeb\xab\xc2\xb8\xb1F\xc1\xc1\x12,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0'
56 2026-03-20 13:36:25.265532 RECEIVED b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fy\x9f'
57 2026-03-20 13:36:26.176979 SENT b'\xbbU\x00\xaah\x01\x05\x18\xe7'
58 2026-03-20 13:36:26.177475 RECEIVED b'\xbb'
59 2026-03-20 13:36:26.177969 RECEIVED b'U\x00\xe9h\x03\x01\x18\xe7T\xa4'
60 2026-03-20 13:36:26.253913 RECEIVED b'\xbb'
61 2026-03-20 13:36:26.254833 RECEIVED b'U\x00Ae\x98\x05\x00\x00\x00\x96\xb3\xd29\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0b\xbc\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xceL\x1d\xc3\x00\x00\x00\x00\x97\x99mB\x00\x00\x00\x00\xc0\x0b\xa3A\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xc4\xec\xaa\xc2\x16pi\xc1\xb47'
62 2026-03-20 13:36:26.255563 RECEIVED b'-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x97\xff'
63 2026-03-20 13:36:27.243846 RECEIVED b'\xbb'
64 2026-03-20 13:36:27.244622 RECEIVED b'U\x00Ae\x98\x06\x00\x00\x00\xc0\xce\xe19\x00\x00\x00\x00\x00\x00\x00\x00\x92\x81\xbc\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\xcd\xcc/\xc3\x00\x00\x00\x00\xcb\xccNB\x00\x00\x00\x00\xc2k\xa5A\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
65 2026-03-20 13:36:27.245273 RECEIVED b'\xf8\x7f\x00\x00\x00\x00q\x88\xaa\xc24os\xc1F0,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'
66 2026-03-20 13:36:27.245761 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f1\xc1'
67 2026-03-20 13:36:28.269778 RECEIVED b'\xbb'
68 2026-03-20 13:36:28.270363 RECEIVED b'U\x00Ae\x98\x05\x00\x00\x00Zv\xf19\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xf7\xbc\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00gf2\xc3\x00\x00\x00\x00\xcb\xccRB\x00\x00\x00\x00YH\x99A\x00\x00\xc0\x7f\x00\x00'
69 2026-03-20 13:36:28.270947 RECEIVED b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00p=\xaa\xc2\xbe\xb6_\xc1\\4-\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'
70 2026-03-20 13:36:28.271457 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xb4\x00'
71 2026-03-20 13:36:29.259732 RECEIVED b'\xbb'
72 2026-03-20 13:36:29.260337 RECEIVED b"U\x00Ae\x98\x04\x00\x00\x00i\x91\x00:\x00\x00\x00\x00\x00\x00\x00\x00\xa3l\xbd\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x9a\x19'\xc3\x00\x00\x00\x00\xfe\xff{B\x00\x00\x00\x00\x04\x91\xa8A\x00\x00\xc0\x7f\x00\x00"
73 2026-03-20 13:36:29.260921 RECEIVED b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00-<\xaa\xc2\xddhu\xc1Y\x8e+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'
74 2026-03-20 13:36:29.261362 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fL='
75 2026-03-20 13:36:30.283273 RECEIVED b'\xbb'
76 2026-03-20 13:36:30.283980 RECEIVED b'U\x00Ae\x98\x06\x00\x00\x00\xea-\x10:\x00\x00\x00\x00\x00\x00\x00\x00%\xe2\xbd\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00433\xc3\x00\x00\x00\x00\xcc\xcc*B\x00\x00\x00\x00\x0b7\x8bA\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
77 2026-03-20 13:36:30.284828 RECEIVED b'\xf8\x7f\x00\x00\x00\x00F\xa1\xa9\xc2@5_\xc1\xd3\xf5,\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x869'
78 2026-03-20 13:36:31.273220 RECEIVED b'\xbb'
79 2026-03-20 13:36:31.273794 RECEIVED b'U\x00Ae\x98\x00\x00\x00\x00\x08I\x1f:\x00\x00\x00\x00\x00\x00\x00\x00\xb0W\xbe\x01\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\x00\x00\x98\x99\xddA\x00\x00\x00\x00\x9a\x99\xe6\xc2\x00\x00\x00\x009\xcc\x92A\x00\x00\xc0\x7f\x00\x00'
80 2026-03-20 13:36:31.274340 RECEIVED b'\xc0\xff\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x82\x95\xa9\xc25\xaf`\xc1\xd2\xf0+\xc3\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xc0\x7f\x00\x00\xc0\xff\x00\x00'
81 2026-03-20 13:36:31.274867 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xf6\xbf'

View File

@@ -0,0 +1,77 @@
2026-03-20 13:35:54.058 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_13-35-54_log_auv.log.
2026-03-20 13:35:54.059 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 13:35:54.059 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_13-35-54_AUV_usbl.csv
2026-03-20 13:35:54.061 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 13:35:54.061 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 13:35:54.082 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 13:35:54.137 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 13:35:54.150 | INFO | __main__:main:136 - set_auto_response_filter(0)=True
2026-03-20 13:35:54.153 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=True
2026-03-20 13:35:54.155 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=True
2026-03-20 13:35:54.155 | INFO | __main__:main:147 - response_received=-1
2026-03-20 13:35:55.156 | INFO | __main__:main:147 - response_received=-1
2026-03-20 13:35:56.156 | INFO | __main__:main:147 - response_received=-1
2026-03-20 13:35:57.157 | INFO | __main__:main:147 - response_received=-1
2026-03-20 13:35:58.157 | INFO | __main__:main:147 - response_received=-1
2026-03-20 13:35:59.158 | INFO | __main__:main:147 - response_received=-1
2026-03-20 13:35:59.192 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:35:59.193 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 255, 'role': 0, 'reserved': 0, 'timestamp_us': 943043765, 'ping_counter': 0, 'carrier_counter': 28288578, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': 91.0, 'azimuth_unc': 0.0, 'elevation_deg': -69.0999984741211, 'elevation_unc': 0.0, 'snr': 17.362789154052734, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -76.49154663085938, 'usbl_pitch': -14.078452110290527, 'usbl_roll': -173.2932891845703, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013759.1926465}
2026-03-20 13:36:00.159 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:00.161 | INFO | __main__:main:154 - antenna.set_auto_response_payload(255)=True
2026-03-20 13:36:01.161 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:02.162 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:03.162 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:03.185 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:03.186 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 255, 'role': 0, 'reserved': 0, 'timestamp_us': 947037042, 'ping_counter': 0, 'carrier_counter': 28408987, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -155.89999389648438, 'azimuth_unc': 0.0, 'elevation_deg': -16.400001525878906, 'elevation_unc': 0.0, 'snr': 17.12036895751953, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -78.55616760253906, 'usbl_pitch': -13.609642028808594, 'usbl_roll': -174.87420654296875, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013763.18576}
2026-03-20 13:36:04.163 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:05.163 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:06.164 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:07.165 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:08.165 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:09.166 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:10.166 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:11.167 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:12.167 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:13.168 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:14.169 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:15.169 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:16.170 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:17.170 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:18.171 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:19.172 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:19.224 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:19.225 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 255, 'role': 0, 'reserved': 0, 'timestamp_us': 963077836, 'ping_counter': 0, 'carrier_counter': 28890433, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -175.8000030517578, 'azimuth_unc': 0.0, 'elevation_deg': 48.999996185302734, 'elevation_unc': 0.0, 'snr': 21.23805809020996, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -86.940185546875, 'usbl_pitch': -14.44540786743164, 'usbl_roll': -171.8121337890625, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013779.2245278}
2026-03-20 13:36:20.172 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:20.250 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:20.251 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 255, 'role': 0, 'reserved': 0, 'timestamp_us': 964103771, 'ping_counter': 0, 'carrier_counter': 28920513, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -170.0, 'azimuth_unc': 0.0, 'elevation_deg': 44.09999465942383, 'elevation_unc': 0.0, 'snr': 19.816301345825195, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -86.58917999267578, 'usbl_pitch': -13.455277442932129, 'usbl_roll': -172.1524200439453, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013780.2505426}
2026-03-20 13:36:21.173 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:22.173 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:22.230 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:22.231 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 255, 'role': 0, 'reserved': 0, 'timestamp_us': 966083764, 'ping_counter': 0, 'carrier_counter': 28980685, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -172.7000274658203, 'azimuth_unc': 0.0, 'elevation_deg': 49.19999313354492, 'elevation_unc': 0.0, 'snr': 21.76565170288086, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -85.80290985107422, 'usbl_pitch': -15.904498100280762, 'usbl_roll': -172.80499267578125, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013782.2305374}
2026-03-20 13:36:23.174 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:23.254 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:23.255 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 255, 'role': 0, 'reserved': 0, 'timestamp_us': 967106844, 'ping_counter': 0, 'carrier_counter': 29010766, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -167.30001831054688, 'azimuth_unc': 0.0, 'elevation_deg': 47.49999237060547, 'elevation_unc': 0.0, 'snr': 19.751195907592773, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -85.63326263427734, 'usbl_pitch': -12.647558212280273, 'usbl_roll': -171.84628295898438, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013783.2544994}
2026-03-20 13:36:24.175 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:25.175 | INFO | __main__:main:147 - response_received=255
2026-03-20 13:36:25.266 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:25.266 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 5, 'role': 0, 'reserved': 0, 'timestamp_us': 969119866, 'ping_counter': 0, 'carrier_counter': 29070948, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -173.6000213623047, 'azimuth_unc': 0.0, 'elevation_deg': 45.399993896484375, 'elevation_unc': 0.0, 'snr': 19.523229598999023, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -85.95982360839844, 'usbl_pitch': -12.418388366699219, 'usbl_roll': -172.07325744628906, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013785.2664862}
2026-03-20 13:36:26.176 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:26.178 | INFO | __main__:main:154 - antenna.set_auto_response_payload(5)=True
2026-03-20 13:36:27.179 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:27.247 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:27.248 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 5, 'role': 0, 'reserved': 0, 'timestamp_us': 971099840, 'ping_counter': 0, 'carrier_counter': 29131154, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -175.8000030517578, 'azimuth_unc': 0.0, 'elevation_deg': 51.69999313354492, 'elevation_unc': 0.0, 'snr': 20.677616119384766, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -85.26648712158203, 'usbl_pitch': -15.214649200439453, 'usbl_roll': -172.18856811523438, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013787.2476614}
2026-03-20 13:36:28.179 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:28.272 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:28.273 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 5, 'role': 0, 'reserved': 0, 'timestamp_us': 972125786, 'ping_counter': 0, 'carrier_counter': 29161247, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -178.40000915527344, 'azimuth_unc': 0.0, 'elevation_deg': 52.69999313354492, 'elevation_unc': 0.0, 'snr': 19.16032600402832, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -85.1199951171875, 'usbl_pitch': -13.982114791870117, 'usbl_roll': -173.20452880859375, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013788.2723386}
2026-03-20 13:36:29.180 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:30.181 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:30.286 | ERROR | kogger_protocol_driver:_reader_thread_loop:544 - Error in precallback for ID 0x65: float modulo
2026-03-20 13:36:30.287 | INFO | __main__:test_callback:57 - test!!!!!!{'id': 5, 'role': 0, 'reserved': 0, 'timestamp_us': 974138858, 'ping_counter': 0, 'carrier_counter': 29221413, 'distance_m': nan, 'distance_unc': 0.0, 'azimuth_deg': -179.20001220703125, 'azimuth_unc': 0.0, 'elevation_deg': 42.69999694824219, 'elevation_unc': 0.0, 'snr': 17.40187644958496, 'beacon_x_m': nan, 'beacon_y_m': nan, 'beacon_latitude': nan, 'beacon_longitude': nan, 'beacon_depth': 0.0, 'usbl_yaw': -84.81498718261719, 'usbl_pitch': -13.95050048828125, 'usbl_roll': -172.9602508544922, 'usbl_latitude': nan, 'usbl_longitude': nan, 'last_iTOW': 0, 'beacon_n_m': nan, 'beacon_e_m': nan, 'code_snr': [nan, nan, nan, nan, nan, nan, nan, nan], 'timestamp_pi': 1774013790.2861822}
2026-03-20 13:36:31.181 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:32.182 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:33.182 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:34.183 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:35.183 | INFO | __main__:main:147 - response_received=5
2026-03-20 13:36:35.605 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 13:36:35.606 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 13:36:35.607 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,7 @@
2026-03-20 14:32:59.498952,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 14:32:59.530348,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:32:59.561610,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 14:32:59.593257,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 14:32:59.624624,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:32:59.645984,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:32:59.667180,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
1 2026-03-20 14:32:59.498952 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 14:32:59.530348 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 14:32:59.561610 SENT b'\xbbU\x00\x03!\x00$K'
4 2026-03-20 14:32:59.593257 SENT b'\xbbU\x00\x03e\x00h\xd3'
5 2026-03-20 14:32:59.624624 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
6 2026-03-20 14:32:59.645984 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
7 2026-03-20 14:32:59.667180 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'

View File

@@ -0,0 +1,28 @@
2026-03-20 14:32:59.493 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-32-59_log_auv.log.
2026-03-20 14:32:59.494 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:32:59.495 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-32-59_AUV_usbl.csv
2026-03-20 14:32:59.497 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:32:59.497 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:32:59.519 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 14:32:59.550 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:32:59.581 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x21
2026-03-20 14:32:59.613 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 14:32:59.644 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:32:59.645 | INFO | __main__:main:136 - set_auto_response_filter(0)=None
2026-03-20 14:32:59.666 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:32:59.666 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:32:59.687 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:32:59.687 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=None
2026-03-20 14:32:59.688 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:00.688 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:01.688 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:02.689 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:03.690 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:04.690 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:05.691 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:06.692 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:07.692 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:08.693 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:33:09.565 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:33:09.566 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:33:09.566 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,7 @@
2026-03-20 14:34:01.918493,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 14:34:01.949800,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:34:01.981096,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 14:34:02.012666,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 14:34:02.043854,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:34:02.064989,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:34:02.086130,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
1 2026-03-20 14:34:01.918493 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 14:34:01.949800 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 14:34:01.981096 SENT b'\xbbU\x00\x03!\x00$K'
4 2026-03-20 14:34:02.012666 SENT b'\xbbU\x00\x03e\x00h\xd3'
5 2026-03-20 14:34:02.043854 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
6 2026-03-20 14:34:02.064989 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
7 2026-03-20 14:34:02.086130 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'

View File

@@ -0,0 +1,23 @@
2026-03-20 14:34:01.914 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-34-01_log_auv.log.
2026-03-20 14:34:01.915 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:34:01.915 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-34-01_AUV_usbl.csv
2026-03-20 14:34:01.917 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:34:01.917 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:34:01.938 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 14:34:01.970 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:34:02.001 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x21
2026-03-20 14:34:02.032 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 14:34:02.064 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:34:02.064 | INFO | __main__:main:136 - set_auto_response_filter(0)=None
2026-03-20 14:34:02.085 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:34:02.085 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:34:02.106 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:34:02.106 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=None
2026-03-20 14:34:02.107 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:34:03.107 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:34:04.108 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:34:05.108 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:34:06.109 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:34:07.052 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:34:07.053 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:34:07.053 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,7 @@
2026-03-20 14:35:07.395381,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 14:35:07.426623,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:35:07.457854,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 14:35:07.489055,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 14:35:07.520263,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:35:07.541942,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:35:07.563092,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
1 2026-03-20 14:35:07.395381 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 14:35:07.426623 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 14:35:07.457854 SENT b'\xbbU\x00\x03!\x00$K'
4 2026-03-20 14:35:07.489055 SENT b'\xbbU\x00\x03e\x00h\xd3'
5 2026-03-20 14:35:07.520263 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
6 2026-03-20 14:35:07.541942 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
7 2026-03-20 14:35:07.563092 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'

View File

@@ -0,0 +1,27 @@
2026-03-20 14:35:07.391 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-35-07_log_auv.log.
2026-03-20 14:35:07.392 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:35:07.392 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-35-07_AUV_usbl.csv
2026-03-20 14:35:07.394 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:35:07.394 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:35:07.415 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 14:35:07.446 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:35:07.478 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x21
2026-03-20 14:35:07.509 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 14:35:07.540 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:35:07.541 | INFO | __main__:main:136 - set_auto_response_filter(0)=None
2026-03-20 14:35:07.562 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:35:07.562 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:35:07.583 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:35:07.583 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=None
2026-03-20 14:35:07.584 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:08.584 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:09.584 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:10.585 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:11.585 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:12.586 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:13.587 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:14.587 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:15.588 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:35:15.953 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:35:15.954 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:35:15.955 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,7 @@
2026-03-20 14:36:35.270157,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 14:36:35.301556,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:36:35.332872,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 14:36:35.363991,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 14:36:35.395159,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:36:35.416269,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:36:35.437376,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
1 2026-03-20 14:36:35.270157 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 14:36:35.301556 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 14:36:35.332872 SENT b'\xbbU\x00\x03!\x00$K'
4 2026-03-20 14:36:35.363991 SENT b'\xbbU\x00\x03e\x00h\xd3'
5 2026-03-20 14:36:35.395159 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
6 2026-03-20 14:36:35.416269 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
7 2026-03-20 14:36:35.437376 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'

View File

@@ -0,0 +1,26 @@
2026-03-20 14:36:35.266 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-36-35_log_auv.log.
2026-03-20 14:36:35.267 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:36:35.267 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-36-35_AUV_usbl.csv
2026-03-20 14:36:35.269 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:36:35.269 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:36:35.290 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 14:36:35.321 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:36:35.353 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x21
2026-03-20 14:36:35.384 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 14:36:35.415 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:36:35.415 | INFO | __main__:main:136 - set_auto_response_filter(0)=None
2026-03-20 14:36:35.436 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:36:35.436 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:36:35.458 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:36:35.458 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=None
2026-03-20 14:36:35.458 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:36.459 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:37.460 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:38.460 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:39.461 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:40.463 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:41.466 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:42.467 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:36:42.632 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:36:42.633 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:36:42.634 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,7 @@
2026-03-20 14:37:46.615358,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 14:37:46.646959,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:37:46.678407,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 14:37:46.710030,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 14:37:46.741664,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:37:46.763085,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:37:46.784460,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
1 2026-03-20 14:37:46.615358 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 14:37:46.646959 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 14:37:46.678407 SENT b'\xbbU\x00\x03!\x00$K'
4 2026-03-20 14:37:46.710030 SENT b'\xbbU\x00\x03e\x00h\xd3'
5 2026-03-20 14:37:46.741664 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
6 2026-03-20 14:37:46.763085 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
7 2026-03-20 14:37:46.784460 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'

View File

@@ -0,0 +1,20 @@
2026-03-20 14:37:46.610 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-37-46_log_auv.log.
2026-03-20 14:37:46.611 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:37:46.611 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-37-46_AUV_usbl.csv
2026-03-20 14:37:46.612 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:37:46.613 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:37:46.635 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 14:37:46.667 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:37:46.698 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x21
2026-03-20 14:37:46.730 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 14:37:46.761 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:46.762 | INFO | __main__:main:136 - set_auto_response_filter(0)=None
2026-03-20 14:37:46.783 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:46.783 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:37:46.804 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:46.805 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=None
2026-03-20 14:37:46.805 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:37:47.806 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:37:48.325 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:37:48.326 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:37:48.326 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,5 @@
2026-03-20 14:37:51.494968,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:37:51.526384,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:37:51.547620,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:37:51.568929,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-20 14:37:51.590691,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
1 2026-03-20 14:37:51.494968 SENT b'\xbbU\x00\x03 \x00#I'
2 2026-03-20 14:37:51.526384 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
3 2026-03-20 14:37:51.547620 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
4 2026-03-20 14:37:51.568929 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
5 2026-03-20 14:37:51.590691 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'

View File

@@ -0,0 +1,16 @@
2026-03-20 14:37:51.490 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-37-51_log_usv.log.
2026-03-20 14:37:51.491 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:37:51.491 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-37-51_AUV_usbl.csv
2026-03-20 14:37:51.493 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:37:51.493 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:37:51.515 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:37:51.546 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:51.547 | INFO | __main__:main:127 - set_auto_response_filter(0)=None
2026-03-20 14:37:51.567 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:51.568 | INFO | __main__:main:129 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:37:51.589 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:51.589 | INFO | __main__:main:131 - set_auto_response_payload(0xff)=None
2026-03-20 14:37:51.610 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:37:52.501 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:37:52.502 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:37:52.502 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,7 @@
2026-03-20 14:44:29.693853,SENT,"b'\xbbU\x00\x03\x04\x00\x07\x11'"
2026-03-20 14:44:29.725054,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:44:29.757207,SENT,"b'\xbbU\x00\x03!\x00$K'"
2026-03-20 14:44:29.790020,SENT,"b'\xbbU\x00\x03e\x00h\xd3'"
2026-03-20 14:44:29.821891,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:44:29.843202,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:44:29.864806,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
1 2026-03-20 14:44:29.693853 SENT b'\xbbU\x00\x03\x04\x00\x07\x11'
2 2026-03-20 14:44:29.725054 SENT b'\xbbU\x00\x03 \x00#I'
3 2026-03-20 14:44:29.757207 SENT b'\xbbU\x00\x03!\x00$K'
4 2026-03-20 14:44:29.790020 SENT b'\xbbU\x00\x03e\x00h\xd3'
5 2026-03-20 14:44:29.821891 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
6 2026-03-20 14:44:29.843202 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
7 2026-03-20 14:44:29.864806 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'

View File

@@ -0,0 +1,21 @@
2026-03-20 14:44:29.689 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-44-29_log_auv.log.
2026-03-20 14:44:29.689 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:44:29.690 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-44-29_AUV_usbl.csv
2026-03-20 14:44:29.692 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:44:29.692 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:44:29.714 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x4
2026-03-20 14:44:29.745 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x20
2026-03-20 14:44:29.777 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x21
2026-03-20 14:44:29.810 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x65
2026-03-20 14:44:29.842 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:44:29.842 | INFO | __main__:main:136 - set_auto_response_filter(0)=None
2026-03-20 14:44:29.863 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:44:29.864 | INFO | __main__:main:138 - set_auto_response_timeout(0xffffffff)=None
2026-03-20 14:44:29.885 | WARNING | kogger_protocol_driver:_execute_command:643 - Timeout waiting for response for command ID 0x68
2026-03-20 14:44:29.886 | INFO | __main__:main:140 - set_auto_response_payload(0xff)=None
2026-03-20 14:44:29.886 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:44:30.886 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:44:31.887 | INFO | __main__:main:147 - response_received=-1
2026-03-20 14:44:32.819 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:44:32.821 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:44:32.822 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,57 @@
2026-03-20 14:56:47.958726,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-20 14:56:47.959041,RECEIVED,"b'\xbb'"
2026-03-20 14:56:47.959643,RECEIVED,"b'U\x00A ""\x00\x0f\x00\x00\x00\x00\x00\x00B\x04\x81(\x00\x02\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xac'"
2026-03-20 14:56:47.970747,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-20 14:56:47.971035,RECEIVED,"b'\xbb'"
2026-03-20 14:56:47.971533,RECEIVED,"b'U\x00\xe1h\x03\x01\x0e\xf2Mk'"
2026-03-20 14:56:47.972554,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-20 14:56:47.972819,RECEIVED,"b'\xbb'"
2026-03-20 14:56:47.973294,RECEIVED,"b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'"
2026-03-20 14:56:47.974430,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-20 14:56:47.974962,RECEIVED,"b'\xbb'"
2026-03-20 14:56:47.975475,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-20 14:56:47.977297,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 14:56:47.977574,RECEIVED,"b'\xbb'"
2026-03-20 14:56:47.978049,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 14:56:48.980709,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 14:56:48.981293,RECEIVED,"b'\xbb'"
2026-03-20 14:56:48.981809,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 14:56:49.983206,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-20 14:56:49.983633,RECEIVED,"b'\xbb'"
2026-03-20 14:56:49.984310,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-20 14:56:50.985612,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:50.986198,RECEIVED,"b'\xbb'"
2026-03-20 14:56:50.986747,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:51.988174,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:51.988630,RECEIVED,"b'\xbb'"
2026-03-20 14:56:51.989155,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:52.991411,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:52.991927,RECEIVED,"b'\xbb'"
2026-03-20 14:56:52.992391,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:53.993851,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:53.994366,RECEIVED,"b'\xbb'"
2026-03-20 14:56:53.994896,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:54.996209,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:54.996536,RECEIVED,"b'\xbb'"
2026-03-20 14:56:54.997075,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:55.998790,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:55.999053,RECEIVED,"b'\xbb'"
2026-03-20 14:56:55.999548,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:57.001186,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:57.001702,RECEIVED,"b'\xbb'"
2026-03-20 14:56:57.002202,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:58.003753,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:58.004379,RECEIVED,"b'\xbb'"
2026-03-20 14:56:58.004967,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:56:59.006241,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:56:59.006573,RECEIVED,"b'\xbb'"
2026-03-20 14:56:59.007106,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:57:00.008571,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:57:00.009919,RECEIVED,"b'\xbb'"
2026-03-20 14:57:00.011049,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:57:01.011479,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:57:01.012009,RECEIVED,"b'\xbb'"
2026-03-20 14:57:01.012508,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-20 14:57:02.013783,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-20 14:57:02.014309,RECEIVED,"b'\xbb'"
2026-03-20 14:57:02.014832,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
1 2026-03-20 14:56:47.958726 SENT b'\xbbU\x00\x03 \x00#I'
2 2026-03-20 14:56:47.959041 RECEIVED b'\xbb'
3 2026-03-20 14:56:47.959643 RECEIVED b'U\x00A "\x00\x0f\x00\x00\x00\x00\x00\x00B\x04\x81(\x00\x02\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xac'
4 2026-03-20 14:56:47.970747 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
5 2026-03-20 14:56:47.971035 RECEIVED b'\xbb'
6 2026-03-20 14:56:47.971533 RECEIVED b'U\x00\xe1h\x03\x01\x0e\xf2Mk'
7 2026-03-20 14:56:47.972554 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
8 2026-03-20 14:56:47.972819 RECEIVED b'\xbb'
9 2026-03-20 14:56:47.973294 RECEIVED b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'
10 2026-03-20 14:56:47.974430 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
11 2026-03-20 14:56:47.974962 RECEIVED b'\xbb'
12 2026-03-20 14:56:47.975475 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
13 2026-03-20 14:56:47.977297 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
14 2026-03-20 14:56:47.977574 RECEIVED b'\xbb'
15 2026-03-20 14:56:47.978049 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
16 2026-03-20 14:56:48.980709 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
17 2026-03-20 14:56:48.981293 RECEIVED b'\xbb'
18 2026-03-20 14:56:48.981809 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
19 2026-03-20 14:56:49.983206 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
20 2026-03-20 14:56:49.983633 RECEIVED b'\xbb'
21 2026-03-20 14:56:49.984310 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
22 2026-03-20 14:56:50.985612 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
23 2026-03-20 14:56:50.986198 RECEIVED b'\xbb'
24 2026-03-20 14:56:50.986747 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
25 2026-03-20 14:56:51.988174 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
26 2026-03-20 14:56:51.988630 RECEIVED b'\xbb'
27 2026-03-20 14:56:51.989155 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
28 2026-03-20 14:56:52.991411 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
29 2026-03-20 14:56:52.991927 RECEIVED b'\xbb'
30 2026-03-20 14:56:52.992391 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
31 2026-03-20 14:56:53.993851 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
32 2026-03-20 14:56:53.994366 RECEIVED b'\xbb'
33 2026-03-20 14:56:53.994896 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
34 2026-03-20 14:56:54.996209 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
35 2026-03-20 14:56:54.996536 RECEIVED b'\xbb'
36 2026-03-20 14:56:54.997075 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
37 2026-03-20 14:56:55.998790 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
38 2026-03-20 14:56:55.999053 RECEIVED b'\xbb'
39 2026-03-20 14:56:55.999548 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
40 2026-03-20 14:56:57.001186 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
41 2026-03-20 14:56:57.001702 RECEIVED b'\xbb'
42 2026-03-20 14:56:57.002202 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
43 2026-03-20 14:56:58.003753 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
44 2026-03-20 14:56:58.004379 RECEIVED b'\xbb'
45 2026-03-20 14:56:58.004967 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
46 2026-03-20 14:56:59.006241 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
47 2026-03-20 14:56:59.006573 RECEIVED b'\xbb'
48 2026-03-20 14:56:59.007106 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
49 2026-03-20 14:57:00.008571 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
50 2026-03-20 14:57:00.009919 RECEIVED b'\xbb'
51 2026-03-20 14:57:00.011049 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
52 2026-03-20 14:57:01.011479 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
53 2026-03-20 14:57:01.012009 RECEIVED b'\xbb'
54 2026-03-20 14:57:01.012508 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
55 2026-03-20 14:57:02.013783 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
56 2026-03-20 14:57:02.014309 RECEIVED b'\xbb'
57 2026-03-20 14:57:02.014832 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'

View File

@@ -0,0 +1,11 @@
2026-03-20 14:56:47.954 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-20_14-56-47_log_usv.log.
2026-03-20 14:56:47.955 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-20 14:56:47.956 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-20_14-56-47_AUV_usbl.csv
2026-03-20 14:56:47.957 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-20 14:56:47.957 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-20 14:56:47.972 | INFO | __main__:main:127 - set_auto_response_filter(0)=True
2026-03-20 14:56:47.973 | INFO | __main__:main:129 - set_auto_response_timeout(0xffffffff)=True
2026-03-20 14:56:47.976 | INFO | __main__:main:131 - set_auto_response_payload(0xff)=True
2026-03-20 14:57:02.116 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-20 14:57:02.117 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-20 14:57:02.117 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,210 @@
2026-03-22 08:42:12.676430,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-22 08:42:12.676791,RECEIVED,"b'\xbb'"
2026-03-22 08:42:12.677342,RECEIVED,"b'U\x00A ""\x00\x0f\x00\x00\x00\x00\x00\x00\x02\x04\x81\t\x00\x02\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004c'"
2026-03-22 08:42:12.688465,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-22 08:42:12.688855,RECEIVED,"b'\xbb'"
2026-03-22 08:42:12.689360,RECEIVED,"b'U\x00\xe1h\x03\x01\x0e\xf2Mk'"
2026-03-22 08:42:12.690520,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-22 08:42:12.690895,RECEIVED,"b'\xbb'"
2026-03-22 08:42:12.691435,RECEIVED,"b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'"
2026-03-22 08:42:12.693535,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-22 08:42:12.693870,RECEIVED,"b'\xbb'"
2026-03-22 08:42:12.694402,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-22 08:42:12.696190,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:12.696502,RECEIVED,"b'\xbb'"
2026-03-22 08:42:12.696979,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:13.019849,RECEIVED,"b'\xbb'"
2026-03-22 08:42:13.020424,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00,]a%\x00\x00\x00\x00\x00\x00\x00\x00:\x0c\x1f\x01\x00\x00\x00\x00\xfa\xc5\xae@\x00\x00\x00\x00\x01\x00\xf9B\x00\x00\x00\x00\xc8\xcc\x8c@\x00\x00\x00\x008C\x95AG\xfcE\xc0\x08\t\x90\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:13.020965,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00%g\xe0AQn:\xc1\xf1*/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xc3\x18\x9b\xc0O!!@\x00\x00'"
2026-03-22 08:42:13.021443,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xc6O'"
2026-03-22 08:42:13.700061,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:13.701084,RECEIVED,"b'\xbb'"
2026-03-22 08:42:13.701628,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:14.045905,RECEIVED,"b'\xbb'"
2026-03-22 08:42:14.046476,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00\xbf\x04q%\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x81\x1f\x01\x00\x00\x00\x00#""\xaa@\x00\x00\x00\x00\xcd\xcc\xfc\xc2\x00\x00\x00\x00\x00\x00L\xc2\x00\x00\x00\x00y\xf4\x98A\xb2\xebI\xc0t\xf0\x88@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:14.046954,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00k\xa7\xedA\xfb\xd0.\xc1@\xc3.C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:14.047444,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x002\xa3\x1e\xbfJ\xf9\xa8\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fg\xfe'"
2026-03-22 08:42:14.702475,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:14.703038,RECEIVED,"b'\xbb'"
2026-03-22 08:42:14.703541,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:15.035878,RECEIVED,"b'\xbb'"
2026-03-22 08:42:15.036461,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\xe6\x1f\x80%\x00\x00\x00\x00\x00\x00\x00\x00S\xf7\x1f\x01\x00\x00\x00\x00*\\\xa9@\x00\x00\x00\x0053\x1e\xc3\x00\x00\x00\x0053u\xc2\x00\x00\x00\x00:\x88\x99A\x97?\x9d\xc0G\x94'"
2026-03-22 08:42:15.036970,RECEIVED,"b'\xfb?\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x15\xdc\xf2AN=9\xc13</C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:15.037428,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00{\xcdO\xc0W\xbe\x85\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x9f\xa8'"
2026-03-22 08:42:15.704791,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:15.705303,RECEIVED,"b'\xbb'"
2026-03-22 08:42:15.705817,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:16.026096,RECEIVED,"b'\xbb'"
2026-03-22 08:42:16.026680,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00!;\x8f%\x00\x00\x00\x00\x00\x00\x00\x00\xd9l \x01\x00\x00\x00\x00\xa8\r\xb8@\x00\x00\x00\x00gf\x0cC\x00\x00\x00\x00\x9a\x99\x05\xc2\x00\x00\x00\x00(q\x94A\xc8\xd0\x8d\xc0\xd8\xa3'"
2026-03-22 08:42:16.027203,RECEIVED,"b""j\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xd6\xf9\xf3A\x8b\xaf9\xc1'\x16/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"""
2026-03-22 08:42:16.027660,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00;\xbc\xb5\xc0\xdd\xf3h?\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x0f-'"
2026-03-22 08:42:16.706987,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:16.707502,RECEIVED,"b'\xbb'"
2026-03-22 08:42:16.707988,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:17.049842,RECEIVED,"b'\xbb'"
2026-03-22 08:42:17.050413,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00A\xd8\x9e%\x00\x00\x00\x00\x00\x00\x00\x00B\xe2 \x01\x00\x00\x00\x00\xd8\xa3\xb2@\x00\x00\x00\x0063\xfbA\x00\x00\x00\x00\x01\x00B\xc2\x00\x00\x00\x00\xb9$\x8fAsz\x98@x%'"
2026-03-22 08:42:17.050884,RECEIVED,"b':\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xf1\x1a\xfbA]n@\xc1\xea\xeb.C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:17.051349,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xac`#@U\xde\x9e@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f/^'"
2026-03-22 08:42:17.709251,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:17.709787,RECEIVED,"b'\xbb'"
2026-03-22 08:42:17.710281,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:18.039899,RECEIVED,"b'\xbb'"
2026-03-22 08:42:18.040479,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00\xad\xf2\xad%\x00\x00\x00\x00\x00\x00\x00\x00\x92W!\x01\x00\x00\x00\x00\xc7\x92\x97@\x00\x00\x00\x0043\x81B\x00\x00\x00\x0013+A\x00\x00\x00\x00\x11#\x9aA\xbe\x07\x02@\xeb\xeb'"
2026-03-22 08:42:18.040954,RECEIVED,"b'\x88\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x11(\x00B\x86\x861\xc1\x8b./C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:18.041412,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xa41\x0c\xbf\x91\x8e\x96@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f&W'"
2026-03-22 08:42:18.712561,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:18.713164,RECEIVED,"b'\xbb'"
2026-03-22 08:42:18.713662,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:19.029913,RECEIVED,"b'\xbb'"
2026-03-22 08:42:19.030461,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00\xdc\r\xbd%\x00\x00\x00\x00\x00\x00\x00\x00a\xcd!\x01\x00\x00\x00\x00-\xf9\xc5@\x00\x00\x00\x00\xcdL\rC\x00\x00\x00\x00\xfe\xff\xffA\x00\x00\x00\x00p\xe0\x9cA""\x81\x9a\xc0\x0f\x90'"
2026-03-22 08:42:19.030941,RECEIVED,"b'w\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00|\xbb\x01B\x06\x00>\xc1\x950/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:19.031409,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00P\xca\xc4\xc0\xe1\xe2,?\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x81\x11'"
2026-03-22 08:42:19.714877,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:42:19.715393,RECEIVED,"b'\xbb'"
2026-03-22 08:42:19.715917,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:42:20.052359,RECEIVED,"b'\xbb'"
2026-03-22 08:42:20.053004,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\xea\xa9\xcc%\x00\x00\x00\x00\x00\x00\x00\x00\xb6B""\x01\x00\x00\x00\x00\xf3\x8b\xaf@\x00\x00\x00\x00\x9e\x99\xb0\xc2\x00\x00\x00\x00ef>B\x00\x00\x00\x00\x151\x97Aw\xa5&>,x\xaf@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:20.056098,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00c\x84\x02B\x8eT7\xc1#\x08/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x8f\xffE@\xe2\xf7\x90\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f$-'"
2026-03-22 08:42:20.717426,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-22 08:42:20.717781,RECEIVED,"b'\xbb'"
2026-03-22 08:42:20.718320,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-22 08:42:21.042938,RECEIVED,"b'\xbb'"
2026-03-22 08:42:21.043644,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00\x86\xc4\xdb%\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xb8""\x01\x00\x00\x00\x00ED\xa6@\x00\x00\x00\x00\x9a\x99\xfdA\x00\x00\x00\x0043?\xc2\x00\x00\x00\x00\xcbq\x8bA\'v\x8d@\xa3\xbc.\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x06\xd7\x03B!n<\xc1\x83\xd3.C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x19R\x0e@\xe6D\x96@\x00\x00\xc0'"
2026-03-22 08:42:21.044334,RECEIVED,"b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x8b.'"
2026-03-22 08:42:21.719886,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-22 08:42:21.720271,RECEIVED,"b'\xbb'"
2026-03-22 08:42:21.720847,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-22 08:42:22.721970,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-22 08:42:22.722483,RECEIVED,"b'\xbb'"
2026-03-22 08:42:22.722977,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-22 08:42:23.724779,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:23.725368,RECEIVED,"b'\xbb'"
2026-03-22 08:42:23.725991,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:24.046169,RECEIVED,"b'\xbb'"
2026-03-22 08:42:24.046902,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00V\x97\t&\x00\x00\x00\x00\x00\x00\x00\x00\xae\x18$\x01\x00\x00\x00\x00r=\xbe@\x00\x00\x00\x00hf\xa6A\x00\x00\x00\x00\x9a\x99\x89\xc1\x00\x00\x00\x00\xa0\x7f\xa6A\\\xd7\xb1@s\x1c'"
2026-03-22 08:42:24.047381,RECEIVED,"b'\x07\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xb4\xe0\x04BF\x9d=\xc1lE/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00>\x89_@\x02\xf2\x99@\x00\x00'"
2026-03-22 08:42:24.047874,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x8a\x8d'"
2026-03-22 08:42:24.727711,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:24.728225,RECEIVED,"b'\xbb'"
2026-03-22 08:42:24.728937,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:25.072187,RECEIVED,"b'\xbb'"
2026-03-22 08:42:25.072760,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00s?\x19&\x00\x00\x00\x00\x00\x00\x00\x00Q\x8e$\x01\x00\x00\x00\x00\xac\xaa\xd4@\x00\x00\x00\x00\xcd\xcc\x19C\x00\x00\x00\x0023\x87A\x00\x00\x00\x00L\xc5\xa5A%\xd1\xbe\xc0\x84\xc9'"
2026-03-22 08:42:25.073230,RECEIVED,"b';\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00dQ\x06B\x1c\xe4D\xc1\xf9i/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:25.073670,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xbc\xe7\xd2\xc06\x85Z\xbf\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f&\xed'"
2026-03-22 08:42:25.730192,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:25.730520,RECEIVED,"b'\xbb'"
2026-03-22 08:42:25.731013,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:26.062249,RECEIVED,"b'\xbb'"
2026-03-22 08:42:26.062824,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\xa3Z(&\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x03%\x01\x00\x00\x00\x00#""\xaa@\x00\x00\x00\x0033\xcdB\x00\x00\x00\x00\x04\x00\xf0\xc0\x00\x00\x00\x00d\xba\x8bA*t\x94\xbf6\t'"
2026-03-22 08:42:26.063301,RECEIVED,"b'\xa6\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x98\x9f\x07B\xa8\xa3=\xc1i\x8b/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:26.063764,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00<\xd8v\xc0\xec2j@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f0\xae'"
2026-03-22 08:42:26.733277,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:26.733832,RECEIVED,"b'\xbb'"
2026-03-22 08:42:26.734331,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:27.736630,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:27.737202,RECEIVED,"b'\xbb'"
2026-03-22 08:42:27.737839,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:28.738809,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:28.739148,RECEIVED,"b'\xbb'"
2026-03-22 08:42:28.739718,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:29.741047,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:29.741606,RECEIVED,"b'\xbb'"
2026-03-22 08:42:29.742409,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:30.056370,RECEIVED,"b'\xbb'"
2026-03-22 08:42:30.057027,RECEIVED,"b'U\x00Ae\x98\x04\x02\x00\x00]He&\x00\x00\x00\x00\x00\x00\x00\x00\xb1\xd9&\x01\x00\x00\x00\x00d\xc9\xbf@\x00\x00\x00\x003\xb3\x02C\x00\x00\x00\x0013\x13A\x00\x00\x00\x00\xbd\xa0\x9aA\xa9 z\xc0kf\x91\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:30.057526,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x82\x8a\x08B\xb5\xef?\xc12j/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xb4\x1b\xb9\xc0\x91\xae\xc8?\x00\x00'"
2026-03-22 08:42:30.057982,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xfb\xd0'"
2026-03-22 08:42:30.744330,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:30.744652,RECEIVED,"b'\xbb'"
2026-03-22 08:42:30.745147,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:31.746296,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:31.746822,RECEIVED,"b'\xbb'"
2026-03-22 08:42:31.747323,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:32.749381,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:32.749901,RECEIVED,"b'\xbb'"
2026-03-22 08:42:32.750437,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:33.752323,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:33.753289,RECEIVED,"b'\xbb'"
2026-03-22 08:42:33.754503,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:34.754901,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:34.755713,RECEIVED,"b'\xbb'"
2026-03-22 08:42:34.761780,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:35.072468,RECEIVED,"b'\xbb'"
2026-03-22 08:42:35.073038,RECEIVED,"b'U\x00Ae\x98\x03\x02\x00\x00\x1c\xd2\xb1&\x00\x00\x00\x00\x00\x00\x00\x00>%)\x01\x00\x00\x00\x00\x86\xeb\xbb@\x00\x00\x00\x00\xcdL\x1c\xc3\x00\x00\x00\x00\xca\xcc\xf4A\x00\x00\x00\x00#C\x90AB\x12\xac\xc0l\x11'"
2026-03-22 08:42:35.073534,RECEIVED,"b'\x17@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x0ba\x11B<?A\xc1\x8c\xab/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:35.074179,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00e\xaa;\xc0\x1f\xd1\xa2\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xa4\xff'"
2026-03-22 08:42:35.757913,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:42:35.758283,RECEIVED,"b'\xbb'"
2026-03-22 08:42:35.758835,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:42:36.760346,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:36.760878,RECEIVED,"b'\xbb'"
2026-03-22 08:42:36.761384,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:37.763574,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:37.763825,RECEIVED,"b'\xbb'"
2026-03-22 08:42:37.764397,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:38.765315,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:38.765640,RECEIVED,"b'\xbb'"
2026-03-22 08:42:38.766128,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:39.767751,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:39.768104,RECEIVED,"b'\xbb'"
2026-03-22 08:42:39.773604,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:40.770578,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:40.771108,RECEIVED,"b'\xbb'"
2026-03-22 08:42:40.771621,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:41.773278,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:41.773875,RECEIVED,"b'\xbb'"
2026-03-22 08:42:41.774400,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:42.776034,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:42.776583,RECEIVED,"b'\xbb'"
2026-03-22 08:42:42.777099,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:43.779192,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:43.779484,RECEIVED,"b'\xbb'"
2026-03-22 08:42:43.780093,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:44.782127,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:44.782468,RECEIVED,"b'\xbb'"
2026-03-22 08:42:44.782990,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:45.784690,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:45.785039,RECEIVED,"b'\xbb'"
2026-03-22 08:42:45.785724,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:46.096839,RECEIVED,"b'\xbb'"
2026-03-22 08:42:46.097418,RECEIVED,"b""U\x00Ae\x98\x02\x02\x00\x008\x0cZ'\x00\x00\x00\x00\x00\x00\x00\x00\xaa1.\x01\x00\x00\x00\x00\xd1i\xb3@\x00\x00\x00\x00\xfa\xffwA\x00\x00\x00\x00133A\x00\x00\x00\x00FP\x8cA_\xe3\xac@\xd2\xc8"""
2026-03-22 08:42:46.097915,RECEIVED,"b'\xbf\xbf\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00s\x8b\x1bB!Y9\xc1)\xb4/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:42:46.098415,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x9f\xf3P@\x1e\xdb\x91@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fNJ'"
2026-03-22 08:42:46.787149,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:46.787669,RECEIVED,"b'\xbb'"
2026-03-22 08:42:46.788171,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:47.789464,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:47.789827,RECEIVED,"b'\xbb'"
2026-03-22 08:42:47.790329,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:48.792614,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:48.793317,RECEIVED,"b'\xbb'"
2026-03-22 08:42:48.793847,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:49.795428,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:49.795920,RECEIVED,"b'\xbb'"
2026-03-22 08:42:49.796435,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:50.797801,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:50.798140,RECEIVED,"b'\xbb'"
2026-03-22 08:42:50.798658,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:51.115137,RECEIVED,"b'\xbb'"
2026-03-22 08:42:51.115758,RECEIVED,"b""U\x00Ae\x98\x03\x02\x00\x00\xdb\xa1\xa6'\x00\x00\x00\x00\x00\x00\x00\x00\x18}0\x01\x00\x00\x00\x00\x08:\xad@\x00\x00\x00\x00\xce\xcc4\xc1\x00\x00\x00\x00\x99\x99\xbdA\x00\x00\x00\x00\x16\xd2\x8fA^\xde\xa9@\xbe\xc5"""
2026-03-22 08:42:51.116735,RECEIVED,"b'\x87?\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00lV\x1fB\xb8\xe8@\xc1;\xa5/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00W/\x98@\xfb~%@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'"
2026-03-22 08:42:51.117453,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x8c%'"
2026-03-22 08:42:51.800453,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:51.800873,RECEIVED,"b'\xbb'"
2026-03-22 08:42:51.801379,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:52.803254,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'"
2026-03-22 08:42:52.803860,RECEIVED,"b'\xbb'"
2026-03-22 08:42:52.804393,RECEIVED,"b'U\x00\xc9h\x03\x01\xf7Fr\x01'"
2026-03-22 08:42:53.805851,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-22 08:42:53.806935,RECEIVED,"b'\xbb'"
2026-03-22 08:42:53.807439,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-22 08:42:54.808323,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-22 08:42:54.808921,RECEIVED,"b'\xbb'"
2026-03-22 08:42:54.809453,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-22 08:42:55.810816,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'"
2026-03-22 08:42:55.811244,RECEIVED,"b'\xbb'"
2026-03-22 08:42:55.812073,RECEIVED,"b'U\x00\xc9h\x03\x01\xf9Hv\x07'"
2026-03-22 08:42:56.135085,RECEIVED,"b'\xbb'"
2026-03-22 08:42:56.135736,RECEIVED,"b""U\x00Ae\x98\x04\x02\x00\x00h7\xf3'\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xc82\x01\x00\x00\x00\x00\x86\xeb\xbb@\x00\x00\x00\x00\x99\x99\xddB\x00\x00\x00\x00\xcc\xcc\x90A\x00\x00\x00\x00\xc7\\\x95A\xa1v\x05\xc0&\xac"""
2026-03-22 08:42:56.136279,RECEIVED,"b'\xaf\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xb2s\x1fB\xee\rD\xc1\xfa\xfe/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xe0\xd1\xa3\xc0%$8@\x00\x00'"
2026-03-22 08:42:56.136867,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fnS'"
1 2026-03-22 08:42:12.676430 SENT b'\xbbU\x00\x03 \x00#I'
2 2026-03-22 08:42:12.676791 RECEIVED b'\xbb'
3 2026-03-22 08:42:12.677342 RECEIVED b'U\x00A "\x00\x0f\x00\x00\x00\x00\x00\x00\x02\x04\x81\t\x00\x02\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004c'
4 2026-03-22 08:42:12.688465 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
5 2026-03-22 08:42:12.688855 RECEIVED b'\xbb'
6 2026-03-22 08:42:12.689360 RECEIVED b'U\x00\xe1h\x03\x01\x0e\xf2Mk'
7 2026-03-22 08:42:12.690520 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
8 2026-03-22 08:42:12.690895 RECEIVED b'\xbb'
9 2026-03-22 08:42:12.691435 RECEIVED b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'
10 2026-03-22 08:42:12.693535 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
11 2026-03-22 08:42:12.693870 RECEIVED b'\xbb'
12 2026-03-22 08:42:12.694402 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
13 2026-03-22 08:42:12.696190 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
14 2026-03-22 08:42:12.696502 RECEIVED b'\xbb'
15 2026-03-22 08:42:12.696979 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
16 2026-03-22 08:42:13.019849 RECEIVED b'\xbb'
17 2026-03-22 08:42:13.020424 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00,]a%\x00\x00\x00\x00\x00\x00\x00\x00:\x0c\x1f\x01\x00\x00\x00\x00\xfa\xc5\xae@\x00\x00\x00\x00\x01\x00\xf9B\x00\x00\x00\x00\xc8\xcc\x8c@\x00\x00\x00\x008C\x95AG\xfcE\xc0\x08\t\x90\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
18 2026-03-22 08:42:13.020965 RECEIVED b'\xf8\x7f\x00\x00\x00\x00%g\xe0AQn:\xc1\xf1*/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xc3\x18\x9b\xc0O!!@\x00\x00'
19 2026-03-22 08:42:13.021443 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xc6O'
20 2026-03-22 08:42:13.700061 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
21 2026-03-22 08:42:13.701084 RECEIVED b'\xbb'
22 2026-03-22 08:42:13.701628 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
23 2026-03-22 08:42:14.045905 RECEIVED b'\xbb'
24 2026-03-22 08:42:14.046476 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00\xbf\x04q%\x00\x00\x00\x00\x00\x00\x00\x00\xe3\x81\x1f\x01\x00\x00\x00\x00#"\xaa@\x00\x00\x00\x00\xcd\xcc\xfc\xc2\x00\x00\x00\x00\x00\x00L\xc2\x00\x00\x00\x00y\xf4\x98A\xb2\xebI\xc0t\xf0\x88@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
25 2026-03-22 08:42:14.046954 RECEIVED b'\xf8\x7f\x00\x00\x00\x00k\xa7\xedA\xfb\xd0.\xc1@\xc3.C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
26 2026-03-22 08:42:14.047444 RECEIVED b'\xf8\x7f\x00\x00\x00\x002\xa3\x1e\xbfJ\xf9\xa8\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fg\xfe'
27 2026-03-22 08:42:14.702475 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
28 2026-03-22 08:42:14.703038 RECEIVED b'\xbb'
29 2026-03-22 08:42:14.703541 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
30 2026-03-22 08:42:15.035878 RECEIVED b'\xbb'
31 2026-03-22 08:42:15.036461 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\xe6\x1f\x80%\x00\x00\x00\x00\x00\x00\x00\x00S\xf7\x1f\x01\x00\x00\x00\x00*\\\xa9@\x00\x00\x00\x0053\x1e\xc3\x00\x00\x00\x0053u\xc2\x00\x00\x00\x00:\x88\x99A\x97?\x9d\xc0G\x94'
32 2026-03-22 08:42:15.036970 RECEIVED b'\xfb?\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x15\xdc\xf2AN=9\xc13</C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
33 2026-03-22 08:42:15.037428 RECEIVED b'\xf8\x7f\x00\x00\x00\x00{\xcdO\xc0W\xbe\x85\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x9f\xa8'
34 2026-03-22 08:42:15.704791 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
35 2026-03-22 08:42:15.705303 RECEIVED b'\xbb'
36 2026-03-22 08:42:15.705817 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
37 2026-03-22 08:42:16.026096 RECEIVED b'\xbb'
38 2026-03-22 08:42:16.026680 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00!;\x8f%\x00\x00\x00\x00\x00\x00\x00\x00\xd9l \x01\x00\x00\x00\x00\xa8\r\xb8@\x00\x00\x00\x00gf\x0cC\x00\x00\x00\x00\x9a\x99\x05\xc2\x00\x00\x00\x00(q\x94A\xc8\xd0\x8d\xc0\xd8\xa3'
39 2026-03-22 08:42:16.027203 RECEIVED b"j\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xd6\xf9\xf3A\x8b\xaf9\xc1'\x16/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"
40 2026-03-22 08:42:16.027660 RECEIVED b'\xf8\x7f\x00\x00\x00\x00;\xbc\xb5\xc0\xdd\xf3h?\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x0f-'
41 2026-03-22 08:42:16.706987 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
42 2026-03-22 08:42:16.707502 RECEIVED b'\xbb'
43 2026-03-22 08:42:16.707988 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
44 2026-03-22 08:42:17.049842 RECEIVED b'\xbb'
45 2026-03-22 08:42:17.050413 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00A\xd8\x9e%\x00\x00\x00\x00\x00\x00\x00\x00B\xe2 \x01\x00\x00\x00\x00\xd8\xa3\xb2@\x00\x00\x00\x0063\xfbA\x00\x00\x00\x00\x01\x00B\xc2\x00\x00\x00\x00\xb9$\x8fAsz\x98@x%'
46 2026-03-22 08:42:17.050884 RECEIVED b':\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xf1\x1a\xfbA]n@\xc1\xea\xeb.C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
47 2026-03-22 08:42:17.051349 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xac`#@U\xde\x9e@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f/^'
48 2026-03-22 08:42:17.709251 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
49 2026-03-22 08:42:17.709787 RECEIVED b'\xbb'
50 2026-03-22 08:42:17.710281 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
51 2026-03-22 08:42:18.039899 RECEIVED b'\xbb'
52 2026-03-22 08:42:18.040479 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00\xad\xf2\xad%\x00\x00\x00\x00\x00\x00\x00\x00\x92W!\x01\x00\x00\x00\x00\xc7\x92\x97@\x00\x00\x00\x0043\x81B\x00\x00\x00\x0013+A\x00\x00\x00\x00\x11#\x9aA\xbe\x07\x02@\xeb\xeb'
53 2026-03-22 08:42:18.040954 RECEIVED b'\x88\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x11(\x00B\x86\x861\xc1\x8b./C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
54 2026-03-22 08:42:18.041412 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xa41\x0c\xbf\x91\x8e\x96@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f&W'
55 2026-03-22 08:42:18.712561 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
56 2026-03-22 08:42:18.713164 RECEIVED b'\xbb'
57 2026-03-22 08:42:18.713662 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
58 2026-03-22 08:42:19.029913 RECEIVED b'\xbb'
59 2026-03-22 08:42:19.030461 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00\xdc\r\xbd%\x00\x00\x00\x00\x00\x00\x00\x00a\xcd!\x01\x00\x00\x00\x00-\xf9\xc5@\x00\x00\x00\x00\xcdL\rC\x00\x00\x00\x00\xfe\xff\xffA\x00\x00\x00\x00p\xe0\x9cA"\x81\x9a\xc0\x0f\x90'
60 2026-03-22 08:42:19.030941 RECEIVED b'w\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00|\xbb\x01B\x06\x00>\xc1\x950/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
61 2026-03-22 08:42:19.031409 RECEIVED b'\xf8\x7f\x00\x00\x00\x00P\xca\xc4\xc0\xe1\xe2,?\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x81\x11'
62 2026-03-22 08:42:19.714877 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
63 2026-03-22 08:42:19.715393 RECEIVED b'\xbb'
64 2026-03-22 08:42:19.715917 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
65 2026-03-22 08:42:20.052359 RECEIVED b'\xbb'
66 2026-03-22 08:42:20.053004 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\xea\xa9\xcc%\x00\x00\x00\x00\x00\x00\x00\x00\xb6B"\x01\x00\x00\x00\x00\xf3\x8b\xaf@\x00\x00\x00\x00\x9e\x99\xb0\xc2\x00\x00\x00\x00ef>B\x00\x00\x00\x00\x151\x97Aw\xa5&>,x\xaf@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
67 2026-03-22 08:42:20.056098 RECEIVED b'\xf8\x7f\x00\x00\x00\x00c\x84\x02B\x8eT7\xc1#\x08/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x8f\xffE@\xe2\xf7\x90\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f$-'
68 2026-03-22 08:42:20.717426 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
69 2026-03-22 08:42:20.717781 RECEIVED b'\xbb'
70 2026-03-22 08:42:20.718320 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
71 2026-03-22 08:42:21.042938 RECEIVED b'\xbb'
72 2026-03-22 08:42:21.043644 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00\x86\xc4\xdb%\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xb8"\x01\x00\x00\x00\x00ED\xa6@\x00\x00\x00\x00\x9a\x99\xfdA\x00\x00\x00\x0043?\xc2\x00\x00\x00\x00\xcbq\x8bA\'v\x8d@\xa3\xbc.\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x06\xd7\x03B!n<\xc1\x83\xd3.C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x19R\x0e@\xe6D\x96@\x00\x00\xc0'
73 2026-03-22 08:42:21.044334 RECEIVED b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x8b.'
74 2026-03-22 08:42:21.719886 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
75 2026-03-22 08:42:21.720271 RECEIVED b'\xbb'
76 2026-03-22 08:42:21.720847 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
77 2026-03-22 08:42:22.721970 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
78 2026-03-22 08:42:22.722483 RECEIVED b'\xbb'
79 2026-03-22 08:42:22.722977 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
80 2026-03-22 08:42:23.724779 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
81 2026-03-22 08:42:23.725368 RECEIVED b'\xbb'
82 2026-03-22 08:42:23.725991 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
83 2026-03-22 08:42:24.046169 RECEIVED b'\xbb'
84 2026-03-22 08:42:24.046902 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00V\x97\t&\x00\x00\x00\x00\x00\x00\x00\x00\xae\x18$\x01\x00\x00\x00\x00r=\xbe@\x00\x00\x00\x00hf\xa6A\x00\x00\x00\x00\x9a\x99\x89\xc1\x00\x00\x00\x00\xa0\x7f\xa6A\\\xd7\xb1@s\x1c'
85 2026-03-22 08:42:24.047381 RECEIVED b'\x07\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xb4\xe0\x04BF\x9d=\xc1lE/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00>\x89_@\x02\xf2\x99@\x00\x00'
86 2026-03-22 08:42:24.047874 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x8a\x8d'
87 2026-03-22 08:42:24.727711 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
88 2026-03-22 08:42:24.728225 RECEIVED b'\xbb'
89 2026-03-22 08:42:24.728937 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
90 2026-03-22 08:42:25.072187 RECEIVED b'\xbb'
91 2026-03-22 08:42:25.072760 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00s?\x19&\x00\x00\x00\x00\x00\x00\x00\x00Q\x8e$\x01\x00\x00\x00\x00\xac\xaa\xd4@\x00\x00\x00\x00\xcd\xcc\x19C\x00\x00\x00\x0023\x87A\x00\x00\x00\x00L\xc5\xa5A%\xd1\xbe\xc0\x84\xc9'
92 2026-03-22 08:42:25.073230 RECEIVED b';\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00dQ\x06B\x1c\xe4D\xc1\xf9i/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
93 2026-03-22 08:42:25.073670 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xbc\xe7\xd2\xc06\x85Z\xbf\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f&\xed'
94 2026-03-22 08:42:25.730192 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
95 2026-03-22 08:42:25.730520 RECEIVED b'\xbb'
96 2026-03-22 08:42:25.731013 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
97 2026-03-22 08:42:26.062249 RECEIVED b'\xbb'
98 2026-03-22 08:42:26.062824 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\xa3Z(&\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x03%\x01\x00\x00\x00\x00#"\xaa@\x00\x00\x00\x0033\xcdB\x00\x00\x00\x00\x04\x00\xf0\xc0\x00\x00\x00\x00d\xba\x8bA*t\x94\xbf6\t'
99 2026-03-22 08:42:26.063301 RECEIVED b'\xa6\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x98\x9f\x07B\xa8\xa3=\xc1i\x8b/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
100 2026-03-22 08:42:26.063764 RECEIVED b'\xf8\x7f\x00\x00\x00\x00<\xd8v\xc0\xec2j@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f0\xae'
101 2026-03-22 08:42:26.733277 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
102 2026-03-22 08:42:26.733832 RECEIVED b'\xbb'
103 2026-03-22 08:42:26.734331 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
104 2026-03-22 08:42:27.736630 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
105 2026-03-22 08:42:27.737202 RECEIVED b'\xbb'
106 2026-03-22 08:42:27.737839 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
107 2026-03-22 08:42:28.738809 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
108 2026-03-22 08:42:28.739148 RECEIVED b'\xbb'
109 2026-03-22 08:42:28.739718 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
110 2026-03-22 08:42:29.741047 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
111 2026-03-22 08:42:29.741606 RECEIVED b'\xbb'
112 2026-03-22 08:42:29.742409 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
113 2026-03-22 08:42:30.056370 RECEIVED b'\xbb'
114 2026-03-22 08:42:30.057027 RECEIVED b'U\x00Ae\x98\x04\x02\x00\x00]He&\x00\x00\x00\x00\x00\x00\x00\x00\xb1\xd9&\x01\x00\x00\x00\x00d\xc9\xbf@\x00\x00\x00\x003\xb3\x02C\x00\x00\x00\x0013\x13A\x00\x00\x00\x00\xbd\xa0\x9aA\xa9 z\xc0kf\x91\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
115 2026-03-22 08:42:30.057526 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x82\x8a\x08B\xb5\xef?\xc12j/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xb4\x1b\xb9\xc0\x91\xae\xc8?\x00\x00'
116 2026-03-22 08:42:30.057982 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xfb\xd0'
117 2026-03-22 08:42:30.744330 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
118 2026-03-22 08:42:30.744652 RECEIVED b'\xbb'
119 2026-03-22 08:42:30.745147 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
120 2026-03-22 08:42:31.746296 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
121 2026-03-22 08:42:31.746822 RECEIVED b'\xbb'
122 2026-03-22 08:42:31.747323 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
123 2026-03-22 08:42:32.749381 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
124 2026-03-22 08:42:32.749901 RECEIVED b'\xbb'
125 2026-03-22 08:42:32.750437 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
126 2026-03-22 08:42:33.752323 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
127 2026-03-22 08:42:33.753289 RECEIVED b'\xbb'
128 2026-03-22 08:42:33.754503 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
129 2026-03-22 08:42:34.754901 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
130 2026-03-22 08:42:34.755713 RECEIVED b'\xbb'
131 2026-03-22 08:42:34.761780 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
132 2026-03-22 08:42:35.072468 RECEIVED b'\xbb'
133 2026-03-22 08:42:35.073038 RECEIVED b'U\x00Ae\x98\x03\x02\x00\x00\x1c\xd2\xb1&\x00\x00\x00\x00\x00\x00\x00\x00>%)\x01\x00\x00\x00\x00\x86\xeb\xbb@\x00\x00\x00\x00\xcdL\x1c\xc3\x00\x00\x00\x00\xca\xcc\xf4A\x00\x00\x00\x00#C\x90AB\x12\xac\xc0l\x11'
134 2026-03-22 08:42:35.073534 RECEIVED b'\x17@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x0ba\x11B<?A\xc1\x8c\xab/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
135 2026-03-22 08:42:35.074179 RECEIVED b'\xf8\x7f\x00\x00\x00\x00e\xaa;\xc0\x1f\xd1\xa2\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xa4\xff'
136 2026-03-22 08:42:35.757913 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
137 2026-03-22 08:42:35.758283 RECEIVED b'\xbb'
138 2026-03-22 08:42:35.758835 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
139 2026-03-22 08:42:36.760346 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
140 2026-03-22 08:42:36.760878 RECEIVED b'\xbb'
141 2026-03-22 08:42:36.761384 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
142 2026-03-22 08:42:37.763574 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
143 2026-03-22 08:42:37.763825 RECEIVED b'\xbb'
144 2026-03-22 08:42:37.764397 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
145 2026-03-22 08:42:38.765315 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
146 2026-03-22 08:42:38.765640 RECEIVED b'\xbb'
147 2026-03-22 08:42:38.766128 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
148 2026-03-22 08:42:39.767751 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
149 2026-03-22 08:42:39.768104 RECEIVED b'\xbb'
150 2026-03-22 08:42:39.773604 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
151 2026-03-22 08:42:40.770578 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
152 2026-03-22 08:42:40.771108 RECEIVED b'\xbb'
153 2026-03-22 08:42:40.771621 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
154 2026-03-22 08:42:41.773278 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
155 2026-03-22 08:42:41.773875 RECEIVED b'\xbb'
156 2026-03-22 08:42:41.774400 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
157 2026-03-22 08:42:42.776034 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
158 2026-03-22 08:42:42.776583 RECEIVED b'\xbb'
159 2026-03-22 08:42:42.777099 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
160 2026-03-22 08:42:43.779192 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
161 2026-03-22 08:42:43.779484 RECEIVED b'\xbb'
162 2026-03-22 08:42:43.780093 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
163 2026-03-22 08:42:44.782127 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
164 2026-03-22 08:42:44.782468 RECEIVED b'\xbb'
165 2026-03-22 08:42:44.782990 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
166 2026-03-22 08:42:45.784690 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
167 2026-03-22 08:42:45.785039 RECEIVED b'\xbb'
168 2026-03-22 08:42:45.785724 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
169 2026-03-22 08:42:46.096839 RECEIVED b'\xbb'
170 2026-03-22 08:42:46.097418 RECEIVED b"U\x00Ae\x98\x02\x02\x00\x008\x0cZ'\x00\x00\x00\x00\x00\x00\x00\x00\xaa1.\x01\x00\x00\x00\x00\xd1i\xb3@\x00\x00\x00\x00\xfa\xffwA\x00\x00\x00\x00133A\x00\x00\x00\x00FP\x8cA_\xe3\xac@\xd2\xc8"
171 2026-03-22 08:42:46.097915 RECEIVED b'\xbf\xbf\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00s\x8b\x1bB!Y9\xc1)\xb4/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
172 2026-03-22 08:42:46.098415 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x9f\xf3P@\x1e\xdb\x91@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fNJ'
173 2026-03-22 08:42:46.787149 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
174 2026-03-22 08:42:46.787669 RECEIVED b'\xbb'
175 2026-03-22 08:42:46.788171 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
176 2026-03-22 08:42:47.789464 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
177 2026-03-22 08:42:47.789827 RECEIVED b'\xbb'
178 2026-03-22 08:42:47.790329 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
179 2026-03-22 08:42:48.792614 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
180 2026-03-22 08:42:48.793317 RECEIVED b'\xbb'
181 2026-03-22 08:42:48.793847 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
182 2026-03-22 08:42:49.795428 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
183 2026-03-22 08:42:49.795920 RECEIVED b'\xbb'
184 2026-03-22 08:42:49.796435 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
185 2026-03-22 08:42:50.797801 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
186 2026-03-22 08:42:50.798140 RECEIVED b'\xbb'
187 2026-03-22 08:42:50.798658 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
188 2026-03-22 08:42:51.115137 RECEIVED b'\xbb'
189 2026-03-22 08:42:51.115758 RECEIVED b"U\x00Ae\x98\x03\x02\x00\x00\xdb\xa1\xa6'\x00\x00\x00\x00\x00\x00\x00\x00\x18}0\x01\x00\x00\x00\x00\x08:\xad@\x00\x00\x00\x00\xce\xcc4\xc1\x00\x00\x00\x00\x99\x99\xbdA\x00\x00\x00\x00\x16\xd2\x8fA^\xde\xa9@\xbe\xc5"
190 2026-03-22 08:42:51.116735 RECEIVED b'\x87?\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00lV\x1fB\xb8\xe8@\xc1;\xa5/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00W/\x98@\xfb~%@\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'
191 2026-03-22 08:42:51.117453 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x8c%'
192 2026-03-22 08:42:51.800453 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
193 2026-03-22 08:42:51.800873 RECEIVED b'\xbb'
194 2026-03-22 08:42:51.801379 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
195 2026-03-22 08:42:52.803254 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x00\xf7F'
196 2026-03-22 08:42:52.803860 RECEIVED b'\xbb'
197 2026-03-22 08:42:52.804393 RECEIVED b'U\x00\xc9h\x03\x01\xf7Fr\x01'
198 2026-03-22 08:42:53.805851 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
199 2026-03-22 08:42:53.806935 RECEIVED b'\xbb'
200 2026-03-22 08:42:53.807439 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
201 2026-03-22 08:42:54.808323 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
202 2026-03-22 08:42:54.808921 RECEIVED b'\xbb'
203 2026-03-22 08:42:54.809453 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
204 2026-03-22 08:42:55.810816 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x02\xf9H'
205 2026-03-22 08:42:55.811244 RECEIVED b'\xbb'
206 2026-03-22 08:42:55.812073 RECEIVED b'U\x00\xc9h\x03\x01\xf9Hv\x07'
207 2026-03-22 08:42:56.135085 RECEIVED b'\xbb'
208 2026-03-22 08:42:56.135736 RECEIVED b"U\x00Ae\x98\x04\x02\x00\x00h7\xf3'\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xc82\x01\x00\x00\x00\x00\x86\xeb\xbb@\x00\x00\x00\x00\x99\x99\xddB\x00\x00\x00\x00\xcc\xcc\x90A\x00\x00\x00\x00\xc7\\\x95A\xa1v\x05\xc0&\xac"
209 2026-03-22 08:42:56.136279 RECEIVED b'\xaf\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xb2s\x1fB\xee\rD\xc1\xfa\xfe/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xe0\xd1\xa3\xc0%$8@\x00\x00'
210 2026-03-22 08:42:56.136867 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fnS'

View File

@@ -0,0 +1,657 @@
2026-03-22 08:42:12.672 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-22_08-42-12_log_usv.log.
2026-03-22 08:42:12.673 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-22 08:42:12.673 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-22_08-42-12_AUV_usbl.csv
2026-03-22 08:42:12.675 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-22 08:42:12.675 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-22 08:42:12.689 | INFO | __main__:main:127 - set_auto_response_filter(0)=True
2026-03-22 08:42:12.692 | INFO | __main__:main:129 - set_auto_response_timeout(0xffffffff)=True
2026-03-22 08:42:12.695 | INFO | __main__:main:131 - set_auto_response_payload(0xff)=True
2026-03-22 08:42:13.022 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 627137836,
"ping_counter": 0,
"carrier_counter": 18811962,
"distance_m": 5.461667060852051,
"distance_unc": 0.0,
"azimuth_deg": 124.50000762939453,
"azimuth_unc": 0.0,
"elevation_deg": 4.399997711181641,
"elevation_unc": 0.0,
"snr": 18.657821655273438,
"beacon_x_m": -3.093522787094116,
"beacon_y_m": -4.501102447509766,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 28.050363540649414,
"usbl_pitch": -11.651932716369629,
"usbl_roll": 175.16773986816406,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -4.84677267074585,
"beacon_e_m": 2.517657995223999,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:14.048 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 628163775,
"ping_counter": 0,
"carrier_counter": 18842083,
"distance_m": 5.316667079925537,
"distance_unc": 0.0,
"azimuth_deg": -126.4000015258789,
"azimuth_unc": 0.0,
"elevation_deg": -51.0,
"elevation_unc": 0.0,
"snr": 19.11937141418457,
"beacon_x_m": -3.15501070022583,
"beacon_y_m": 4.279352188110352,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 29.70674705505371,
"usbl_pitch": -10.926020622253418,
"usbl_roll": 174.7626953125,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -0.6196776628494263,
"beacon_e_m": -5.280430793762207,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:15.038 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 629153766,
"ping_counter": 0,
"carrier_counter": 18872147,
"distance_m": 5.2925004959106445,
"distance_unc": 0.0,
"azimuth_deg": -158.2000274658203,
"azimuth_unc": 0.0,
"elevation_deg": -61.30000686645508,
"elevation_unc": 0.0,
"snr": 19.191516876220703,
"beacon_x_m": -4.914012432098389,
"beacon_y_m": 1.965462565422058,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 30.35746192932129,
"usbl_pitch": -11.57746696472168,
"usbl_roll": 175.2351531982422,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -3.2469165325164795,
"beacon_e_m": -4.179484844207764,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:16.028 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 630143777,
"ping_counter": 0,
"carrier_counter": 18902233,
"distance_m": 5.751667022705078,
"distance_unc": 0.0,
"azimuth_deg": 140.40000915527344,
"azimuth_unc": 0.0,
"elevation_deg": -33.400001525878906,
"elevation_unc": 0.0,
"snr": 18.555252075195312,
"beacon_x_m": -4.431735992431641,
"beacon_y_m": -3.666250228881836,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 30.496990203857422,
"usbl_pitch": -11.60535717010498,
"usbl_roll": 175.08653259277344,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -5.679227352142334,
"beacon_e_m": 0.9099710583686829,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:17.052 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 631167041,
"ping_counter": 0,
"carrier_counter": 18932290,
"distance_m": 5.582500457763672,
"distance_unc": 0.0,
"azimuth_deg": 31.400005340576172,
"azimuth_unc": 0.0,
"elevation_deg": -48.500003814697266,
"elevation_unc": 0.0,
"snr": 17.89293098449707,
"beacon_x_m": 4.764947414398193,
"beacon_y_m": -2.908536911010742,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 31.388154983520508,
"usbl_pitch": -12.026944160461426,
"usbl_roll": 174.92153930664062,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 2.5527753829956055,
"beacon_e_m": 4.964640140533447,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:18.042 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 632156845,
"ping_counter": 0,
"carrier_counter": 18962322,
"distance_m": 4.736667156219482,
"distance_unc": 0.0,
"azimuth_deg": 64.60000610351562,
"azimuth_unc": 0.0,
"elevation_deg": 10.699997901916504,
"elevation_unc": 0.0,
"snr": 19.267122268676758,
"beacon_x_m": 2.0317225456237793,
"beacon_y_m": -4.278798580169678,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 32.039127349853516,
"usbl_pitch": -11.095342636108398,
"usbl_roll": 175.1818084716797,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -0.5476324558258057,
"beacon_e_m": 4.7049031257629395,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:19.032 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 633146844,
"ping_counter": 0,
"carrier_counter": 18992481,
"distance_m": 6.186666965484619,
"distance_unc": 0.0,
"azimuth_deg": 141.3000030517578,
"azimuth_unc": 0.0,
"elevation_deg": 31.999996185302734,
"elevation_unc": 0.0,
"snr": 19.609588623046875,
"beacon_x_m": -4.828263282775879,
"beacon_y_m": -3.8681676387786865,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 32.43309020996094,
"usbl_pitch": -11.875005722045898,
"usbl_roll": 175.1897735595703,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -6.149696350097656,
"beacon_e_m": 0.6753368973731995,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:20.057 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 634169834,
"ping_counter": 0,
"carrier_counter": 19022518,
"distance_m": 5.485833644866943,
"distance_unc": 0.0,
"azimuth_deg": -88.30003356933594,
"azimuth_unc": 0.0,
"elevation_deg": 47.59999465942383,
"elevation_unc": 0.0,
"snr": 18.89896583557129,
"beacon_x_m": 0.1627405732870102,
"beacon_y_m": 5.483419418334961,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 32.6292839050293,
"usbl_pitch": -11.45814323425293,
"usbl_roll": 175.0317840576172,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 3.0937230587005615,
"beacon_e_m": -4.530259132385254,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:21.045 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 635159686,
"ping_counter": 0,
"carrier_counter": 19052574,
"distance_m": 5.195833683013916,
"distance_unc": 0.0,
"azimuth_deg": 31.700000762939453,
"azimuth_unc": 0.0,
"elevation_deg": -47.80000305175781,
"elevation_unc": 0.0,
"snr": 17.43056297302246,
"beacon_x_m": 4.42067289352417,
"beacon_y_m": -2.7302634716033936,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 32.959983825683594,
"usbl_pitch": -11.776886940002441,
"usbl_roll": 174.8262176513672,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 2.2237608432769775,
"beacon_e_m": 4.695910453796387,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:24.048 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 638162774,
"ping_counter": 0,
"carrier_counter": 19142830,
"distance_m": 5.945000648498535,
"distance_unc": 0.0,
"azimuth_deg": 20.800003051757812,
"azimuth_unc": 0.0,
"elevation_deg": -17.200000762939453,
"elevation_unc": 0.0,
"snr": 20.81231689453125,
"beacon_x_m": 5.557538986206055,
"beacon_y_m": -2.1111114025115967,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 33.21943664550781,
"usbl_pitch": -11.850896835327148,
"usbl_roll": 175.27117919921875,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 3.4927515983581543,
"beacon_e_m": 4.810791969299316,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:25.074 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 639188851,
"ping_counter": 0,
"carrier_counter": 19172945,
"distance_m": 6.645833969116211,
"distance_unc": 0.0,
"azimuth_deg": 153.8000030517578,
"azimuth_unc": 0.0,
"elevation_deg": 16.89999771118164,
"elevation_unc": 0.0,
"snr": 20.721336364746094,
"beacon_x_m": -5.9630303382873535,
"beacon_y_m": -2.9341745376586914,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 33.57948303222656,
"usbl_pitch": -12.30569076538086,
"usbl_roll": 175.41395568847656,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -6.590787887573242,
"beacon_e_m": -0.8535951375961304,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:26.064 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 640178851,
"ping_counter": 0,
"carrier_counter": 19202958,
"distance_m": 5.316667079925537,
"distance_unc": 0.0,
"azimuth_deg": 102.5999984741211,
"azimuth_unc": 0.0,
"elevation_deg": -7.500001907348633,
"elevation_unc": 0.0,
"snr": 17.46601104736328,
"beacon_x_m": -1.1597950458526611,
"beacon_y_m": -5.188624382019043,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 33.905853271484375,
"usbl_pitch": -11.852455139160156,
"usbl_roll": 175.54457092285156,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -3.856947898864746,
"beacon_e_m": 3.659358024597168,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:30.058 | INFO | __main__:print_message:34 - printer:{
"id": 4,
"role": 2,
"reserved": 0,
"timestamp_us": 644171869,
"ping_counter": 0,
"carrier_counter": 19323313,
"distance_m": 5.99333381652832,
"distance_unc": 0.0,
"azimuth_deg": 130.6999969482422,
"azimuth_unc": 0.0,
"elevation_deg": 9.199997901916504,
"elevation_unc": 0.0,
"snr": 19.3284854888916,
"beacon_x_m": -3.908243417739868,
"beacon_y_m": -4.543752193450928,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 34.13526153564453,
"usbl_pitch": -11.99602222442627,
"usbl_roll": 175.41482543945312,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -5.784631729125977,
"beacon_e_m": 1.5678273439407349,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:35.075 | INFO | __main__:print_message:34 - printer:{
"id": 3,
"role": 2,
"reserved": 0,
"timestamp_us": 649187868,
"ping_counter": 0,
"carrier_counter": 19473726,
"distance_m": 5.872500419616699,
"distance_unc": 0.0,
"azimuth_deg": -156.3000030517578,
"azimuth_unc": 0.0,
"elevation_deg": 30.599994659423828,
"elevation_unc": 0.0,
"snr": 18.03278160095215,
"beacon_x_m": -5.377228736877441,
"beacon_y_m": 2.360438346862793,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 36.34476852416992,
"usbl_pitch": -12.077938079833984,
"usbl_roll": 175.67010498046875,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.9322750568389893,
"beacon_e_m": -5.088027477264404,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:46.099 | INFO | __main__:print_message:34 - printer:{
"id": 2,
"role": 2,
"reserved": 0,
"timestamp_us": 660212792,
"ping_counter": 0,
"carrier_counter": 19804586,
"distance_m": 5.6066670417785645,
"distance_unc": 0.0,
"azimuth_deg": 15.499994277954102,
"azimuth_unc": 0.0,
"elevation_deg": 11.199997901916504,
"elevation_unc": 0.0,
"snr": 17.539196014404297,
"beacon_x_m": 5.402755260467529,
"beacon_y_m": -1.4983160495758057,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 38.88618087768555,
"usbl_pitch": -11.584259986877441,
"usbl_roll": 175.70375061035156,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 3.264869451522827,
"beacon_e_m": 4.557997703552246,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:51.118 | INFO | __main__:print_message:34 - printer:{
"id": 3,
"role": 2,
"reserved": 0,
"timestamp_us": 665231835,
"ping_counter": 0,
"carrier_counter": 19954968,
"distance_m": 5.413333892822266,
"distance_unc": 0.0,
"azimuth_deg": -11.30000114440918,
"azimuth_unc": 0.0,
"elevation_deg": 23.69999885559082,
"elevation_unc": 0.0,
"snr": 17.977581024169922,
"beacon_x_m": 5.308394432067871,
"beacon_y_m": 1.0607221126556396,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 39.83439636230469,
"usbl_pitch": -12.056816101074219,
"usbl_roll": 175.6454315185547,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 4.755778789520264,
"beacon_e_m": 2.5858752727508545,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:56.137 | INFO | __main__:print_message:34 - printer:{
"id": 4,
"role": 2,
"reserved": 0,
"timestamp_us": 670250856,
"ping_counter": 0,
"carrier_counter": 20105377,
"distance_m": 5.872500419616699,
"distance_unc": 0.0,
"azimuth_deg": 110.79999542236328,
"azimuth_unc": 0.0,
"elevation_deg": 18.099998474121094,
"elevation_unc": 0.0,
"snr": 18.67030143737793,
"beacon_x_m": -2.0853655338287354,
"beacon_y_m": -5.489764213562012,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 39.86298370361328,
"usbl_pitch": -12.253400802612305,
"usbl_roll": 175.99600219726562,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -5.1193695068359375,
"beacon_e_m": 2.8772060871124268,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:42:56.239 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-22 08:42:56.240 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-22 08:42:56.240 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

View File

@@ -0,0 +1,185 @@
2026-03-22 08:49:18.972082,SENT,"b'\xbbU\x00\x03 \x00#I'"
2026-03-22 08:49:18.972768,RECEIVED,"b'\xbb'"
2026-03-22 08:49:18.973369,RECEIVED,"b'U\x00A ""\x00\x0f\x00\x00\x00\x00\x00\x00\x02\x04\x81\t\x00\x02\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004c'"
2026-03-22 08:49:18.984533,SENT,"b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'"
2026-03-22 08:49:18.984859,RECEIVED,"b'\xbb'"
2026-03-22 08:49:18.985355,RECEIVED,"b'U\x00\xe1h\x03\x01\x0e\xf2Mk'"
2026-03-22 08:49:18.986432,SENT,"b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'"
2026-03-22 08:49:18.986807,RECEIVED,"b'\xbb'"
2026-03-22 08:49:18.987333,RECEIVED,"b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'"
2026-03-22 08:49:18.988343,SENT,"b'\xbbU\x00\xaah\x01\xff\x12\xe1'"
2026-03-22 08:49:18.988616,RECEIVED,"b'\xbb'"
2026-03-22 08:49:18.989203,RECEIVED,"b'U\x00\xe9h\x03\x01\x12\xe1H\x92'"
2026-03-22 08:49:18.990998,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:18.991275,RECEIVED,"b'\xbb'"
2026-03-22 08:49:18.991772,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:19.320330,RECEIVED,"b'\xbb'"
2026-03-22 08:49:19.320945,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00w\x0c\xca>\x00\x00\x00\x00\x00\x00\x00\x00\x9c/\xe2\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\xcd\xcc\xa8B\x00\x00\x00\x00if\x96\xc0\x00\x00\x00\x00\x11k\x8dA9\x06\x06?T\xdc\xaa\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:19.321420,RECEIVED,"b""\xf8\x7f\x00\x00\x00\x00LI\x04C\xbd'(\xc1:\xff/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"""
2026-03-22 08:49:19.322031,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00c\xac\x89\xc0\x81""M\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fi\x94'"
2026-03-22 08:49:19.994056,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:19.994661,RECEIVED,"b'\xbb'"
2026-03-22 08:49:19.995180,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:20.310453,RECEIVED,"b'\xbb'"
2026-03-22 08:49:20.311181,RECEIVED,"b""U\x00Ae\x98\xff\x02\x00\x00\xad'\xd9>\x00\x00\x00\x00\x00\x00\x00\x008\xa5\xe2\x01\x00\x00\x00\x00\xca/\xb4@\x00\x00\x00\x00\x00\x00\xddB\x00\x00\x00\x00\x00\x00`\xc2\x00\x00\x00\x002\x8b\x90A-i\xfc\xbf\x9e\xc6\xa8\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"""
2026-03-22 08:49:20.311786,RECEIVED,"b""\xf8\x7f\x00\x00\x00\x00\x15\xb8\x03C \xe87\xc1)\x1e1C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xa1\xf7'\xc0\xeaj\x9f\xc0\x00\x00"""
2026-03-22 08:49:20.312648,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x97o'"
2026-03-22 08:49:20.996393,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:20.996719,RECEIVED,"b'\xbb'"
2026-03-22 08:49:20.997201,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:21.999021,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:21.999632,RECEIVED,"b'\xbb'"
2026-03-22 08:49:22.000160,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:22.326766,RECEIVED,"b'\xbb'"
2026-03-22 08:49:22.327492,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x00H\xea\xf7>\x00\x00\x00\x00\x00\x00\x00\x00*\x90\xe3\x01\x00\x00\x00\x00\xca/\xb4@\x00\x00\x00\x00\x9a\x99\xd7B\x00\x00\x00\x00gf<\xc2\x00\x00\x00\x00\xfc\xb4\x8dA3T\xdc\xbf\x9f\x8f\xab\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xedJ\x04C\x08\x9e2\xc1V\xe10'"
2026-03-22 08:49:22.328481,RECEIVED,"b'C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x7f\xae3\xc0\x171\x9c\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xda\xde'"
2026-03-22 08:49:23.001397,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:23.001928,RECEIVED,"b'\xbb'"
2026-03-22 08:49:23.002825,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:23.316892,RECEIVED,"b'\xbb'"
2026-03-22 08:49:23.317468,RECEIVED,"b'U\x00Ae\x98\x02\x02\x00\x00x\x05\x07?\x00\x00\x00\x00\x00\x00\x00\x00\x97\x05\xe4\x01\x00\x00\x00\x00\xe6\x17\xb1@\x00\x00\x00\x00ff\xceB\x00\x00\x00\x00_fF@\x00\x00\x00\x00\xb6\x81\x8aA\xf7\xc1\xa1\xbf\x13j\xac\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:23.317998,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xe2.\x05C\xce\xf1-\xc1fM0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00A\x17D\xc0\xd7y\x93\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'"
2026-03-22 08:49:23.318464,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x9c+'"
2026-03-22 08:49:24.004559,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:24.004925,RECEIVED,"b'\xbb'"
2026-03-22 08:49:24.005435,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:24.338848,RECEIVED,"b'\xbb'"
2026-03-22 08:49:24.339449,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\xdd\xa1\x16?\x00\x00\x00\x00\x00\x00\x00\x00\x1c{\xe4\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\xcc\xcc\xdbB\x00\x00\x00\x00\x9a\x99\xb9\xc1\x00\x00\x00\x00\xa6\x9d\x8aA\xd0\xbe\xe9\xbf\xbfm\xa1\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8'"
2026-03-22 08:49:24.339950,RECEIVED,"b'\x7f\x00\x00\x00\x00\x8b1\x05C\xe9z3\xc13\xd10C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xf8a\x1b\xc0S\x18\x99\xc0\x00\x00\xc0'"
2026-03-22 08:49:24.340418,RECEIVED,"b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x10['"
2026-03-22 08:49:25.007423,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:25.007952,RECEIVED,"b'\xbb'"
2026-03-22 08:49:25.008466,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:25.328822,RECEIVED,"b'\xbb'"
2026-03-22 08:49:25.329412,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\x1c\xbd%?\x00\x00\x00\x00\x00\x00\x00\x00\xa5\xf0\xe4\x01\x00\x00\x00\x00\x1c\xe8\xaa@\x00\x00\x00\x0033\x8cB\x00\x00\x00\x00\xce\xcc\x04\xc1\x00\x00\x00\x00\xe5\xb2\x8aAJ\xb1\xe8?\x97\xb3'"
2026-03-22 08:49:25.329900,RECEIVED,"b'\xa0\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x19\x84\x05C\x01\x01)\xc1\x83k0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:25.330363,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xe9\x97\x9c\xc0\x9e\xee\x08\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xdd\xf8'"
2026-03-22 08:49:26.009881,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:26.010385,RECEIVED,"b'\xbb'"
2026-03-22 08:49:26.010900,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:26.352850,RECEIVED,"b'\xbb'"
2026-03-22 08:49:26.353470,RECEIVED,"b'U\x00Ae\x98\x02\x02\x00\x00%Y5?\x00\x00\x00\x00\x00\x00\x00\x00\x1cf\xe5\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x9a\x99\xfc\xc2\x00\x00\x00\x00\x99\x99\xcf\xc2\x00\x00\x00\x00\x8b\xf5\x88A\x11FK\xc0\x9d\\\x8a@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:26.354141,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00 \x8d\x05C\xf0d2\xc1Q\xcb0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x95N\xaa@L[-?\x00\x00'"
2026-03-22 08:49:26.354705,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xec\xbd'"
2026-03-22 08:49:27.013270,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:27.013859,RECEIVED,"b'\xbb'"
2026-03-22 08:49:27.014393,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:27.343058,RECEIVED,"b'\xbb'"
2026-03-22 08:49:27.344325,RECEIVED,"b'U\x00Ae\x98\x02\x02\x00\x00ctD?\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xdb\xe5\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00nf\x16A\x00\x00\x00\x0053Q\xc2\x00\x00\x00\x00\x85\xa0\x8aA\xee_\xa9@\x90Q`\xbf\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00 \xa4\x05C\xb5\xe33\xc1\x84z0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x14/\x89\xc0=qN@\x00\x00\xc0'"
2026-03-22 08:49:27.345087,RECEIVED,"b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f,\x90'"
2026-03-22 08:49:28.016585,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:28.017111,RECEIVED,"b'\xbb'"
2026-03-22 08:49:28.017618,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:28.332984,RECEIVED,"b'\xbb'"
2026-03-22 08:49:28.333555,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\x06\x8fS?\x00\x00\x00\x00\x00\x00\x00\x00@Q\xe6\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x00\x00\xabB\x00\x00\x00\x0043U\xc2\x00\x00\x00\x00\x13\xee\x8bA\x89\x84\xd7>\x9a&\xab\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:28.334041,RECEIVED,"b""\xf8\x7f\x00\x00\x00\x005\xd5\x05C\xc0\x9a'\xc1\x8c\xcd0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"""
2026-03-22 08:49:28.334515,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00b\xca\x84\xc0D\xa1Y\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xb6\x91'"
2026-03-22 08:49:29.019293,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:29.019650,RECEIVED,"b'\xbb'"
2026-03-22 08:49:29.020177,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:29.359080,RECEIVED,"b'\xbb'"
2026-03-22 08:49:29.359711,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00i7c?\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xc6\xe6\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x0033\xe7B\x00\x00\x00\x00gf\x0c\xc2\x00\x00\x00\x00\xc9\xd9\x8dAg\\\x14\xc0\x9f\xd3\x9a\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:29.360190,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xd7""\x06C\x8c\xae0\xc1o\xa40C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x8d\xd7\xed\xbf\xe5\r\xa1\xc0\x00\x00'"
2026-03-22 08:49:29.360692,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xbe\xda'"
2026-03-22 08:49:30.022268,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:30.022543,RECEIVED,"b'\xbb'"
2026-03-22 08:49:30.023194,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:30.345253,RECEIVED,"b'\xbb'"
2026-03-22 08:49:30.345883,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\x9aFr?\x00\x00\x00\x00\x00\x00\x00\x007<\xe7\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x00\x00\xf7B\x00\x00\x00\x00\xce\xcc4\xc1\x00\x00\x00\x00b\xc7\x8eAZ\x83=\xc0[)'"
2026-03-22 08:49:30.346382,RECEIVED,"b'\x8f\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\n\xb4\x06C\x9a\x9f,\xc1Zp0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:30.346902,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xa0d\x8c\xbf\xd2\r\xa8\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x1d\xa0'"
2026-03-22 08:49:31.024770,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:31.025084,RECEIVED,"b'\xbb'"
2026-03-22 08:49:31.025581,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:31.335278,RECEIVED,"b'\xbb'"
2026-03-22 08:49:31.335932,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\xb0a\x81?\x00\x00\x00\x00\x00\x00\x00\x00\xb6\xb1\xe7\x01\x00\x00\x00\x00*\\\xa9@\x00\x00\x00\x00\x00\x00\xd0B\x00\x00\x00\x00\xca\xcc\x14A\x00\x00\x00\x00\xf4\x01\x8aA8\xe3\xa3\xbfMT\xa4\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:31.336408,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x97\xdb\x06Cy\x98-\xc1b\xae0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x82,/\xc0\xf2\xf3\x90\xc0\x00\x00'"
2026-03-22 08:49:31.336887,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xf2/'"
2026-03-22 08:49:32.027680,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:32.028236,RECEIVED,"b'\xbb'"
2026-03-22 08:49:32.028809,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:33.030181,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:33.030720,RECEIVED,"b'\xbb'"
2026-03-22 08:49:33.031228,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:33.351370,RECEIVED,"b'\xbb'"
2026-03-22 08:49:33.352271,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\xfc$\xa0?\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x9c\xe8\x01\x00\x00\x00\x00\x1c\xe8\xaa@\x00\x00\x00\x00hfPB\x00\x00\x00\x0043m\xc2\x00\x00\x00\x00~Q\x89A\x8a\xf8Q@\x18\xdc\x86\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x003\x87\x06C\xad?6\xc1F\xc1'"
2026-03-22 08:49:33.352866,RECEIVED,"b'0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xae\xc3\xa9\xc0\x8f\xd0\x1d\xbf\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x97\\'"
2026-03-22 08:49:34.032995,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'"
2026-03-22 08:49:34.033323,RECEIVED,"b'\xbb'"
2026-03-22 08:49:34.033819,RECEIVED,"b'U\x00\xc9h\x03\x01\xf6Ep\xfe'"
2026-03-22 08:49:35.036321,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:49:35.036952,RECEIVED,"b'\xbb'"
2026-03-22 08:49:35.037569,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:49:35.365256,RECEIVED,"b'\xbb'"
2026-03-22 08:49:35.365836,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00\x0c\xdc\xbe?\x00\x00\x00\x00\x00\x00\x00\x00\xd3\x87\xe9\x01\x00\x00\x00\x001\x96\xa8@\x00\x00\x00\x00\xcd\xcc\xcbB\x00\x00\x00\x00jf\xd6\xc0\x00\x00\x00\x00\x90D\x8bA\x9b\r\x8b\xbf\xad\xf6'"
2026-03-22 08:49:35.366324,RECEIVED,"b'\xa4\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x08\x11\x08C\x880-\xc1\xa0\xa10C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:35.366788,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00z\xd72\xc0\xda\xea\x8e\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xa5\x05'"
2026-03-22 08:49:36.038249,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:49:36.038754,RECEIVED,"b'\xbb'"
2026-03-22 08:49:36.039303,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:49:36.355301,RECEIVED,"b'\xbb'"
2026-03-22 08:49:36.355931,RECEIVED,"b'U\x00Ae\x98\xff\x02\x00\x007\xf7\xcd?\x00\x00\x00\x00\x00\x00\x00\x00J\xfd\xe9\x01\x00\x00\x00\x00\xc4\xf5\xb4@\x00\x00\x00\x00ff\xeaB\x00\x00\x00\x00\x00\x000\xc2\x00\x00\x00\x00\xad%\x93A\xd0n%\xc0\xe5\xf2\xa0\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:36.356425,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\x1d\x16\x08CO).\xc1\x96\xb30C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x07+\xd0\xbf\xb1P\xad\xc0\x00\x00'"
2026-03-22 08:49:36.356885,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xe5G'"
2026-03-22 08:49:37.041131,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:49:37.041826,RECEIVED,"b'\xbb'"
2026-03-22 08:49:37.043030,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:49:37.377740,RECEIVED,"b'\xbb'"
2026-03-22 08:49:37.378313,RECEIVED,"b'U\x00Ae\x98\x01\x02\x00\x00I\x93\xdd?\x00\x00\x00\x00\x00\x00\x00\x00\xc3r\xea\x01\x00\x00\x00\x00#""\xaa@\x00\x00\x00\x00ff\xd1B\x00\x00\x00\x00\xcc\xcc\x1eB\x00\x00\x00\x00:\x0c\x8dA\xd3\xb0\xac\xbf\x83\x90'"
2026-03-22 08:49:37.378790,RECEIVED,"b'\xa4\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00L#\x08C\xdd\x93*\xc1\\\xa10C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:37.379263,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00U\xce%\xc0h\x91\x94\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x86\x83'"
2026-03-22 08:49:38.044385,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'"
2026-03-22 08:49:38.044926,RECEIVED,"b'\xbb'"
2026-03-22 08:49:38.045522,RECEIVED,"b'U\x00\xc9h\x03\x01\xfaIx\n'"
2026-03-22 08:49:39.047282,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:39.047813,RECEIVED,"b'\xbb'"
2026-03-22 08:49:39.048302,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:40.049807,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:40.050570,RECEIVED,"b'\xbb'"
2026-03-22 08:49:40.051108,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:41.052835,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:41.053106,RECEIVED,"b'\xbb'"
2026-03-22 08:49:41.053597,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:41.373764,RECEIVED,"b'\xbb'"
2026-03-22 08:49:41.374375,RECEIVED,"b'U\x00Ae\x98\x08\x02\x00\x00\xfc\x8c\x1a@\x00\x00\x00\x00\x00\x00\x00\x00\xdaH\xec\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x99\x99\xd9A\x00\x00\x00\x00\x99\x99SB\x00\x00\x00\x00E\xee\x8bA\xed\xb1\x98@\xfc\xf2\x1c\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:41.374836,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00`&\tC\xe2\x9d(\xc1\xee\xdb0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xbaP\xa5\xc0@@\xb9?\x00\x00'"
2026-03-22 08:49:41.375301,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fk\x85'"
2026-03-22 08:49:42.056010,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:42.056670,RECEIVED,"b'\xbb'"
2026-03-22 08:49:42.057272,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:43.058914,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:43.059513,RECEIVED,"b'\xbb'"
2026-03-22 08:49:43.062982,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:44.061647,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:44.062382,RECEIVED,"b'\xbb'"
2026-03-22 08:49:44.063010,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:44.377544,RECEIVED,"b'\xbb'"
2026-03-22 08:49:44.378149,RECEIVED,"b'U\x00Ae\x98\x08\x02\x00\x00(_H@\x00\x00\x00\x00\x00\x00\x00\x00|\xa9\xed\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00ef\xc0B\x00\x00\x00\x00433\xc2\x00\x00\x00\x008\xe7\x89A\x97T\x14\xbf\x06\xad'"
2026-03-22 08:49:44.378655,RECEIVED,"b'\xaa\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xf18\nC\x04-)\xc1s\x8d0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:44.379154,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00\xbd\xc4G\xc0\xdc\xa1\x8b\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f.\xaf'"
2026-03-22 08:49:45.064388,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:45.064911,RECEIVED,"b'\xbb'"
2026-03-22 08:49:45.065407,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:46.066894,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:46.067216,RECEIVED,"b'\xbb'"
2026-03-22 08:49:46.067719,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:46.389483,RECEIVED,"b'\xbb'"
2026-03-22 08:49:46.390101,RECEIVED,"b'U\x00Ae\x98\x08\x02\x00\x00\xc8\x16g@\x00\x00\x00\x00\x00\x00\x00\x00o\x94\xee\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x9a\x99\x90B\x00\x00\x00\x00\xcd\xcc\x12\xc2\x00\x00\x00\x00\x18\xb6\x8cA\x1a\xc9\xd0?\x8e\x8d'"
2026-03-22 08:49:46.390584,RECEIVED,"b'\xa3\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00&\x8d\nC\x16\xa0!\xc1\xe8>0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:46.391094,RECEIVED,"b""\xf8\x7f\x00\x00\x00\x00-c\x93\xc0P\x140\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f'\xfe"""
2026-03-22 08:49:47.069257,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:47.069783,RECEIVED,"b'\xbb'"
2026-03-22 08:49:47.070282,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:48.072188,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:48.079211,RECEIVED,"b'\xbb'"
2026-03-22 08:49:48.079786,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:49.074749,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:49.075073,RECEIVED,"b'\xbb'"
2026-03-22 08:49:49.075583,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
2026-03-22 08:49:49.393552,RECEIVED,"b'\xbb'"
2026-03-22 08:49:49.394184,RECEIVED,"b'U\x00Ae\x98\x08\x02\x00\x00\xb6\xea\x94@\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xf4\xef\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00f\xe6,C\x00\x00\x00\x00hf>\xc1\x00\x00\x00\x00+\xf0\x8fA\x13]\xaa\xc0d\xc2)\xbf\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'"
2026-03-22 08:49:49.394754,RECEIVED,"b'\xf8\x7f\x00\x00\x00\x00a\xf7\nC\x9b\x1b0\xc1G\x9e0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00#(e@\x9a\xb3\x7f\xc0\x00\x00'"
2026-03-22 08:49:49.395271,RECEIVED,"b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x87%'"
2026-03-22 08:49:50.077293,SENT,"b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'"
2026-03-22 08:49:50.077812,RECEIVED,"b'\xbb'"
2026-03-22 08:49:50.078301,RECEIVED,"b'U\x00\xc9h\x03\x01\xfbJz\r'"
1 2026-03-22 08:49:18.972082 SENT b'\xbbU\x00\x03 \x00#I'
2 2026-03-22 08:49:18.972768 RECEIVED b'\xbb'
3 2026-03-22 08:49:18.973369 RECEIVED b'U\x00A "\x00\x0f\x00\x00\x00\x00\x00\x00\x02\x04\x81\t\x00\x02\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004c'
4 2026-03-22 08:49:18.984533 SENT b'\xbbU\x00\xa2h\x04\x00\x00\x00\x00\x0e\xf2'
5 2026-03-22 08:49:18.984859 RECEIVED b'\xbb'
6 2026-03-22 08:49:18.985355 RECEIVED b'U\x00\xe1h\x03\x01\x0e\xf2Mk'
7 2026-03-22 08:49:18.986432 SENT b'\xbbU\x00\x9ah\x04\xff\xff\xff\xff\x02\xb0'
8 2026-03-22 08:49:18.986807 RECEIVED b'\xbb'
9 2026-03-22 08:49:18.987333 RECEIVED b'U\x00\xd9h\x03\x01\x02\xb0\xf7\xe1'
10 2026-03-22 08:49:18.988343 SENT b'\xbbU\x00\xaah\x01\xff\x12\xe1'
11 2026-03-22 08:49:18.988616 RECEIVED b'\xbb'
12 2026-03-22 08:49:18.989203 RECEIVED b'U\x00\xe9h\x03\x01\x12\xe1H\x92'
13 2026-03-22 08:49:18.990998 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
14 2026-03-22 08:49:18.991275 RECEIVED b'\xbb'
15 2026-03-22 08:49:18.991772 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
16 2026-03-22 08:49:19.320330 RECEIVED b'\xbb'
17 2026-03-22 08:49:19.320945 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00w\x0c\xca>\x00\x00\x00\x00\x00\x00\x00\x00\x9c/\xe2\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\xcd\xcc\xa8B\x00\x00\x00\x00if\x96\xc0\x00\x00\x00\x00\x11k\x8dA9\x06\x06?T\xdc\xaa\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
18 2026-03-22 08:49:19.321420 RECEIVED b"\xf8\x7f\x00\x00\x00\x00LI\x04C\xbd'(\xc1:\xff/C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"
19 2026-03-22 08:49:19.322031 RECEIVED b'\xf8\x7f\x00\x00\x00\x00c\xac\x89\xc0\x81"M\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fi\x94'
20 2026-03-22 08:49:19.994056 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
21 2026-03-22 08:49:19.994661 RECEIVED b'\xbb'
22 2026-03-22 08:49:19.995180 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
23 2026-03-22 08:49:20.310453 RECEIVED b'\xbb'
24 2026-03-22 08:49:20.311181 RECEIVED b"U\x00Ae\x98\xff\x02\x00\x00\xad'\xd9>\x00\x00\x00\x00\x00\x00\x00\x008\xa5\xe2\x01\x00\x00\x00\x00\xca/\xb4@\x00\x00\x00\x00\x00\x00\xddB\x00\x00\x00\x00\x00\x00`\xc2\x00\x00\x00\x002\x8b\x90A-i\xfc\xbf\x9e\xc6\xa8\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"
25 2026-03-22 08:49:20.311786 RECEIVED b"\xf8\x7f\x00\x00\x00\x00\x15\xb8\x03C \xe87\xc1)\x1e1C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xa1\xf7'\xc0\xeaj\x9f\xc0\x00\x00"
26 2026-03-22 08:49:20.312648 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x97o'
27 2026-03-22 08:49:20.996393 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
28 2026-03-22 08:49:20.996719 RECEIVED b'\xbb'
29 2026-03-22 08:49:20.997201 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
30 2026-03-22 08:49:21.999021 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
31 2026-03-22 08:49:21.999632 RECEIVED b'\xbb'
32 2026-03-22 08:49:22.000160 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
33 2026-03-22 08:49:22.326766 RECEIVED b'\xbb'
34 2026-03-22 08:49:22.327492 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x00H\xea\xf7>\x00\x00\x00\x00\x00\x00\x00\x00*\x90\xe3\x01\x00\x00\x00\x00\xca/\xb4@\x00\x00\x00\x00\x9a\x99\xd7B\x00\x00\x00\x00gf<\xc2\x00\x00\x00\x00\xfc\xb4\x8dA3T\xdc\xbf\x9f\x8f\xab\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xedJ\x04C\x08\x9e2\xc1V\xe10'
35 2026-03-22 08:49:22.328481 RECEIVED b'C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x7f\xae3\xc0\x171\x9c\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xda\xde'
36 2026-03-22 08:49:23.001397 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
37 2026-03-22 08:49:23.001928 RECEIVED b'\xbb'
38 2026-03-22 08:49:23.002825 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
39 2026-03-22 08:49:23.316892 RECEIVED b'\xbb'
40 2026-03-22 08:49:23.317468 RECEIVED b'U\x00Ae\x98\x02\x02\x00\x00x\x05\x07?\x00\x00\x00\x00\x00\x00\x00\x00\x97\x05\xe4\x01\x00\x00\x00\x00\xe6\x17\xb1@\x00\x00\x00\x00ff\xceB\x00\x00\x00\x00_fF@\x00\x00\x00\x00\xb6\x81\x8aA\xf7\xc1\xa1\xbf\x13j\xac\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
41 2026-03-22 08:49:23.317998 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xe2.\x05C\xce\xf1-\xc1fM0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00A\x17D\xc0\xd7y\x93\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00'
42 2026-03-22 08:49:23.318464 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x9c+'
43 2026-03-22 08:49:24.004559 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
44 2026-03-22 08:49:24.004925 RECEIVED b'\xbb'
45 2026-03-22 08:49:24.005435 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
46 2026-03-22 08:49:24.338848 RECEIVED b'\xbb'
47 2026-03-22 08:49:24.339449 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\xdd\xa1\x16?\x00\x00\x00\x00\x00\x00\x00\x00\x1c{\xe4\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\xcc\xcc\xdbB\x00\x00\x00\x00\x9a\x99\xb9\xc1\x00\x00\x00\x00\xa6\x9d\x8aA\xd0\xbe\xe9\xbf\xbfm\xa1\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8'
48 2026-03-22 08:49:24.339950 RECEIVED b'\x7f\x00\x00\x00\x00\x8b1\x05C\xe9z3\xc13\xd10C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xf8a\x1b\xc0S\x18\x99\xc0\x00\x00\xc0'
49 2026-03-22 08:49:24.340418 RECEIVED b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x10['
50 2026-03-22 08:49:25.007423 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
51 2026-03-22 08:49:25.007952 RECEIVED b'\xbb'
52 2026-03-22 08:49:25.008466 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
53 2026-03-22 08:49:25.328822 RECEIVED b'\xbb'
54 2026-03-22 08:49:25.329412 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\x1c\xbd%?\x00\x00\x00\x00\x00\x00\x00\x00\xa5\xf0\xe4\x01\x00\x00\x00\x00\x1c\xe8\xaa@\x00\x00\x00\x0033\x8cB\x00\x00\x00\x00\xce\xcc\x04\xc1\x00\x00\x00\x00\xe5\xb2\x8aAJ\xb1\xe8?\x97\xb3'
55 2026-03-22 08:49:25.329900 RECEIVED b'\xa0\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x19\x84\x05C\x01\x01)\xc1\x83k0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
56 2026-03-22 08:49:25.330363 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xe9\x97\x9c\xc0\x9e\xee\x08\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xdd\xf8'
57 2026-03-22 08:49:26.009881 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
58 2026-03-22 08:49:26.010385 RECEIVED b'\xbb'
59 2026-03-22 08:49:26.010900 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
60 2026-03-22 08:49:26.352850 RECEIVED b'\xbb'
61 2026-03-22 08:49:26.353470 RECEIVED b'U\x00Ae\x98\x02\x02\x00\x00%Y5?\x00\x00\x00\x00\x00\x00\x00\x00\x1cf\xe5\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x9a\x99\xfc\xc2\x00\x00\x00\x00\x99\x99\xcf\xc2\x00\x00\x00\x00\x8b\xf5\x88A\x11FK\xc0\x9d\\\x8a@\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
62 2026-03-22 08:49:26.354141 RECEIVED b'\xf8\x7f\x00\x00\x00\x00 \x8d\x05C\xf0d2\xc1Q\xcb0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x95N\xaa@L[-?\x00\x00'
63 2026-03-22 08:49:26.354705 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xec\xbd'
64 2026-03-22 08:49:27.013270 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
65 2026-03-22 08:49:27.013859 RECEIVED b'\xbb'
66 2026-03-22 08:49:27.014393 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
67 2026-03-22 08:49:27.343058 RECEIVED b'\xbb'
68 2026-03-22 08:49:27.344325 RECEIVED b'U\x00Ae\x98\x02\x02\x00\x00ctD?\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xdb\xe5\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00nf\x16A\x00\x00\x00\x0053Q\xc2\x00\x00\x00\x00\x85\xa0\x8aA\xee_\xa9@\x90Q`\xbf\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00 \xa4\x05C\xb5\xe33\xc1\x84z0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x14/\x89\xc0=qN@\x00\x00\xc0'
69 2026-03-22 08:49:27.345087 RECEIVED b'\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f,\x90'
70 2026-03-22 08:49:28.016585 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
71 2026-03-22 08:49:28.017111 RECEIVED b'\xbb'
72 2026-03-22 08:49:28.017618 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
73 2026-03-22 08:49:28.332984 RECEIVED b'\xbb'
74 2026-03-22 08:49:28.333555 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\x06\x8fS?\x00\x00\x00\x00\x00\x00\x00\x00@Q\xe6\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x00\x00\xabB\x00\x00\x00\x0043U\xc2\x00\x00\x00\x00\x13\xee\x8bA\x89\x84\xd7>\x9a&\xab\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
75 2026-03-22 08:49:28.334041 RECEIVED b"\xf8\x7f\x00\x00\x00\x005\xd5\x05C\xc0\x9a'\xc1\x8c\xcd0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00"
76 2026-03-22 08:49:28.334515 RECEIVED b'\xf8\x7f\x00\x00\x00\x00b\xca\x84\xc0D\xa1Y\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xb6\x91'
77 2026-03-22 08:49:29.019293 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
78 2026-03-22 08:49:29.019650 RECEIVED b'\xbb'
79 2026-03-22 08:49:29.020177 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
80 2026-03-22 08:49:29.359080 RECEIVED b'\xbb'
81 2026-03-22 08:49:29.359711 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00i7c?\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xc6\xe6\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x0033\xe7B\x00\x00\x00\x00gf\x0c\xc2\x00\x00\x00\x00\xc9\xd9\x8dAg\\\x14\xc0\x9f\xd3\x9a\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
82 2026-03-22 08:49:29.360190 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xd7"\x06C\x8c\xae0\xc1o\xa40C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x8d\xd7\xed\xbf\xe5\r\xa1\xc0\x00\x00'
83 2026-03-22 08:49:29.360692 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xbe\xda'
84 2026-03-22 08:49:30.022268 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
85 2026-03-22 08:49:30.022543 RECEIVED b'\xbb'
86 2026-03-22 08:49:30.023194 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
87 2026-03-22 08:49:30.345253 RECEIVED b'\xbb'
88 2026-03-22 08:49:30.345883 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\x9aFr?\x00\x00\x00\x00\x00\x00\x00\x007<\xe7\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x00\x00\xf7B\x00\x00\x00\x00\xce\xcc4\xc1\x00\x00\x00\x00b\xc7\x8eAZ\x83=\xc0[)'
89 2026-03-22 08:49:30.346382 RECEIVED b'\x8f\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\n\xb4\x06C\x9a\x9f,\xc1Zp0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
90 2026-03-22 08:49:30.346902 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xa0d\x8c\xbf\xd2\r\xa8\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x1d\xa0'
91 2026-03-22 08:49:31.024770 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
92 2026-03-22 08:49:31.025084 RECEIVED b'\xbb'
93 2026-03-22 08:49:31.025581 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
94 2026-03-22 08:49:31.335278 RECEIVED b'\xbb'
95 2026-03-22 08:49:31.335932 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\xb0a\x81?\x00\x00\x00\x00\x00\x00\x00\x00\xb6\xb1\xe7\x01\x00\x00\x00\x00*\\\xa9@\x00\x00\x00\x00\x00\x00\xd0B\x00\x00\x00\x00\xca\xcc\x14A\x00\x00\x00\x00\xf4\x01\x8aA8\xe3\xa3\xbfMT\xa4\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
96 2026-03-22 08:49:31.336408 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x97\xdb\x06Cy\x98-\xc1b\xae0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x82,/\xc0\xf2\xf3\x90\xc0\x00\x00'
97 2026-03-22 08:49:31.336887 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xf2/'
98 2026-03-22 08:49:32.027680 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
99 2026-03-22 08:49:32.028236 RECEIVED b'\xbb'
100 2026-03-22 08:49:32.028809 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
101 2026-03-22 08:49:33.030181 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
102 2026-03-22 08:49:33.030720 RECEIVED b'\xbb'
103 2026-03-22 08:49:33.031228 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
104 2026-03-22 08:49:33.351370 RECEIVED b'\xbb'
105 2026-03-22 08:49:33.352271 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\xfc$\xa0?\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x9c\xe8\x01\x00\x00\x00\x00\x1c\xe8\xaa@\x00\x00\x00\x00hfPB\x00\x00\x00\x0043m\xc2\x00\x00\x00\x00~Q\x89A\x8a\xf8Q@\x18\xdc\x86\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x003\x87\x06C\xad?6\xc1F\xc1'
106 2026-03-22 08:49:33.352866 RECEIVED b'0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xae\xc3\xa9\xc0\x8f\xd0\x1d\xbf\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x97\\'
107 2026-03-22 08:49:34.032995 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\xff\xf6E'
108 2026-03-22 08:49:34.033323 RECEIVED b'\xbb'
109 2026-03-22 08:49:34.033819 RECEIVED b'U\x00\xc9h\x03\x01\xf6Ep\xfe'
110 2026-03-22 08:49:35.036321 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
111 2026-03-22 08:49:35.036952 RECEIVED b'\xbb'
112 2026-03-22 08:49:35.037569 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
113 2026-03-22 08:49:35.365256 RECEIVED b'\xbb'
114 2026-03-22 08:49:35.365836 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00\x0c\xdc\xbe?\x00\x00\x00\x00\x00\x00\x00\x00\xd3\x87\xe9\x01\x00\x00\x00\x001\x96\xa8@\x00\x00\x00\x00\xcd\xcc\xcbB\x00\x00\x00\x00jf\xd6\xc0\x00\x00\x00\x00\x90D\x8bA\x9b\r\x8b\xbf\xad\xf6'
115 2026-03-22 08:49:35.366324 RECEIVED b'\xa4\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x08\x11\x08C\x880-\xc1\xa0\xa10C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
116 2026-03-22 08:49:35.366788 RECEIVED b'\xf8\x7f\x00\x00\x00\x00z\xd72\xc0\xda\xea\x8e\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xa5\x05'
117 2026-03-22 08:49:36.038249 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
118 2026-03-22 08:49:36.038754 RECEIVED b'\xbb'
119 2026-03-22 08:49:36.039303 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
120 2026-03-22 08:49:36.355301 RECEIVED b'\xbb'
121 2026-03-22 08:49:36.355931 RECEIVED b'U\x00Ae\x98\xff\x02\x00\x007\xf7\xcd?\x00\x00\x00\x00\x00\x00\x00\x00J\xfd\xe9\x01\x00\x00\x00\x00\xc4\xf5\xb4@\x00\x00\x00\x00ff\xeaB\x00\x00\x00\x00\x00\x000\xc2\x00\x00\x00\x00\xad%\x93A\xd0n%\xc0\xe5\xf2\xa0\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
122 2026-03-22 08:49:36.356425 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\x1d\x16\x08CO).\xc1\x96\xb30C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x07+\xd0\xbf\xb1P\xad\xc0\x00\x00'
123 2026-03-22 08:49:36.356885 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\xe5G'
124 2026-03-22 08:49:37.041131 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
125 2026-03-22 08:49:37.041826 RECEIVED b'\xbb'
126 2026-03-22 08:49:37.043030 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
127 2026-03-22 08:49:37.377740 RECEIVED b'\xbb'
128 2026-03-22 08:49:37.378313 RECEIVED b'U\x00Ae\x98\x01\x02\x00\x00I\x93\xdd?\x00\x00\x00\x00\x00\x00\x00\x00\xc3r\xea\x01\x00\x00\x00\x00#"\xaa@\x00\x00\x00\x00ff\xd1B\x00\x00\x00\x00\xcc\xcc\x1eB\x00\x00\x00\x00:\x0c\x8dA\xd3\xb0\xac\xbf\x83\x90'
129 2026-03-22 08:49:37.378790 RECEIVED b'\xa4\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00L#\x08C\xdd\x93*\xc1\\\xa10C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
130 2026-03-22 08:49:37.379263 RECEIVED b'\xf8\x7f\x00\x00\x00\x00U\xce%\xc0h\x91\x94\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x86\x83'
131 2026-03-22 08:49:38.044385 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x03\xfaI'
132 2026-03-22 08:49:38.044926 RECEIVED b'\xbb'
133 2026-03-22 08:49:38.045522 RECEIVED b'U\x00\xc9h\x03\x01\xfaIx\n'
134 2026-03-22 08:49:39.047282 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
135 2026-03-22 08:49:39.047813 RECEIVED b'\xbb'
136 2026-03-22 08:49:39.048302 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
137 2026-03-22 08:49:40.049807 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
138 2026-03-22 08:49:40.050570 RECEIVED b'\xbb'
139 2026-03-22 08:49:40.051108 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
140 2026-03-22 08:49:41.052835 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
141 2026-03-22 08:49:41.053106 RECEIVED b'\xbb'
142 2026-03-22 08:49:41.053597 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
143 2026-03-22 08:49:41.373764 RECEIVED b'\xbb'
144 2026-03-22 08:49:41.374375 RECEIVED b'U\x00Ae\x98\x08\x02\x00\x00\xfc\x8c\x1a@\x00\x00\x00\x00\x00\x00\x00\x00\xdaH\xec\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x99\x99\xd9A\x00\x00\x00\x00\x99\x99SB\x00\x00\x00\x00E\xee\x8bA\xed\xb1\x98@\xfc\xf2\x1c\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
145 2026-03-22 08:49:41.374836 RECEIVED b'\xf8\x7f\x00\x00\x00\x00`&\tC\xe2\x9d(\xc1\xee\xdb0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xbaP\xa5\xc0@@\xb9?\x00\x00'
146 2026-03-22 08:49:41.375301 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7fk\x85'
147 2026-03-22 08:49:42.056010 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
148 2026-03-22 08:49:42.056670 RECEIVED b'\xbb'
149 2026-03-22 08:49:42.057272 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
150 2026-03-22 08:49:43.058914 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
151 2026-03-22 08:49:43.059513 RECEIVED b'\xbb'
152 2026-03-22 08:49:43.062982 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
153 2026-03-22 08:49:44.061647 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
154 2026-03-22 08:49:44.062382 RECEIVED b'\xbb'
155 2026-03-22 08:49:44.063010 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
156 2026-03-22 08:49:44.377544 RECEIVED b'\xbb'
157 2026-03-22 08:49:44.378149 RECEIVED b'U\x00Ae\x98\x08\x02\x00\x00(_H@\x00\x00\x00\x00\x00\x00\x00\x00|\xa9\xed\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00ef\xc0B\x00\x00\x00\x00433\xc2\x00\x00\x00\x008\xe7\x89A\x97T\x14\xbf\x06\xad'
158 2026-03-22 08:49:44.378655 RECEIVED b'\xaa\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\xf18\nC\x04-)\xc1s\x8d0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
159 2026-03-22 08:49:44.379154 RECEIVED b'\xf8\x7f\x00\x00\x00\x00\xbd\xc4G\xc0\xdc\xa1\x8b\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f.\xaf'
160 2026-03-22 08:49:45.064388 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
161 2026-03-22 08:49:45.064911 RECEIVED b'\xbb'
162 2026-03-22 08:49:45.065407 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
163 2026-03-22 08:49:46.066894 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
164 2026-03-22 08:49:46.067216 RECEIVED b'\xbb'
165 2026-03-22 08:49:46.067719 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
166 2026-03-22 08:49:46.389483 RECEIVED b'\xbb'
167 2026-03-22 08:49:46.390101 RECEIVED b'U\x00Ae\x98\x08\x02\x00\x00\xc8\x16g@\x00\x00\x00\x00\x00\x00\x00\x00o\x94\xee\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00\x9a\x99\x90B\x00\x00\x00\x00\xcd\xcc\x12\xc2\x00\x00\x00\x00\x18\xb6\x8cA\x1a\xc9\xd0?\x8e\x8d'
168 2026-03-22 08:49:46.390584 RECEIVED b'\xa3\xc0\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00&\x8d\nC\x16\xa0!\xc1\xe8>0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
169 2026-03-22 08:49:46.391094 RECEIVED b"\xf8\x7f\x00\x00\x00\x00-c\x93\xc0P\x140\xc0\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f'\xfe"
170 2026-03-22 08:49:47.069257 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
171 2026-03-22 08:49:47.069783 RECEIVED b'\xbb'
172 2026-03-22 08:49:47.070282 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
173 2026-03-22 08:49:48.072188 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
174 2026-03-22 08:49:48.079211 RECEIVED b'\xbb'
175 2026-03-22 08:49:48.079786 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
176 2026-03-22 08:49:49.074749 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
177 2026-03-22 08:49:49.075073 RECEIVED b'\xbb'
178 2026-03-22 08:49:49.075583 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'
179 2026-03-22 08:49:49.393552 RECEIVED b'\xbb'
180 2026-03-22 08:49:49.394184 RECEIVED b'U\x00Ae\x98\x08\x02\x00\x00\xb6\xea\x94@\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xf4\xef\x01\x00\x00\x00\x00\x16\xae\xab@\x00\x00\x00\x00f\xe6,C\x00\x00\x00\x00hf>\xc1\x00\x00\x00\x00+\xf0\x8fA\x13]\xaa\xc0d\xc2)\xbf\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00'
181 2026-03-22 08:49:49.394754 RECEIVED b'\xf8\x7f\x00\x00\x00\x00a\xf7\nC\x9b\x1b0\xc1G\x9e0C\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00\x00\x00\xf8\x7f\x00\x00\x00\x00#(e@\x9a\xb3\x7f\xc0\x00\x00'
182 2026-03-22 08:49:49.395271 RECEIVED b'\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x00\x00\xc0\x7f\x87%'
183 2026-03-22 08:49:50.077293 SENT b'\xbbU\x00\x8ah\x05\x00\x00\x00\x00\x04\xfbJ'
184 2026-03-22 08:49:50.077812 RECEIVED b'\xbb'
185 2026-03-22 08:49:50.078301 RECEIVED b'U\x00\xc9h\x03\x01\xfbJz\r'

View File

@@ -0,0 +1,771 @@
2026-03-22 08:49:18.968 | INFO | kogger_protocol_driver:setup_logging:81 - Kogger Protocol Driver: Loguru logging configured to level INFO and file log/2026-03-22_08-49-18_log_usv.log.
2026-03-22 08:49:18.968 | INFO | kogger_protocol_driver:__init__:224 - KoggerSBPDevice configured for port /dev/ttyAMA4, baudrate 921600, address 0
2026-03-22 08:49:18.969 | INFO | kogger_protocol_driver:_open_file:43 - CSV logging enabled to log/2026-03-22_08-49-18_AUV_usbl.csv
2026-03-22 08:49:18.970 | INFO | kogger_protocol_driver:_reader_thread_loop:491 - Reader thread started.
2026-03-22 08:49:18.971 | SUCCESS | kogger_protocol_driver:connect:314 - Successfully connected to /dev/ttyAMA4 at 921600 and started reader thread.
2026-03-22 08:49:18.985 | INFO | __main__:main:127 - set_auto_response_filter(0)=True
2026-03-22 08:49:18.987 | INFO | __main__:main:129 - set_auto_response_timeout(0xffffffff)=True
2026-03-22 08:49:18.989 | INFO | __main__:main:131 - set_auto_response_payload(0xff)=True
2026-03-22 08:49:19.323 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1053428855,
"ping_counter": 0,
"carrier_counter": 31600540,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 84.4000015258789,
"azimuth_unc": 0.0,
"elevation_deg": -4.700001239776611,
"elevation_unc": 0.0,
"snr": 17.677278518676758,
"beacon_x_m": 0.5235324501991272,
"beacon_y_m": -5.339395523071289,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 132.28631591796875,
"usbl_pitch": -10.5097017288208,
"usbl_roll": 175.99697875976562,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -4.302293300628662,
"beacon_e_m": -3.205230951309204,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:20.314 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 1054418861,
"ping_counter": 0,
"carrier_counter": 31630648,
"distance_m": 5.630833625793457,
"distance_unc": 0.0,
"azimuth_deg": 110.5,
"azimuth_unc": 0.0,
"elevation_deg": -56.0,
"elevation_unc": 0.0,
"snr": 18.06796646118164,
"beacon_x_m": -1.9719597101211548,
"beacon_y_m": -5.274245262145996,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 131.7190704345703,
"usbl_pitch": -11.494171142578125,
"usbl_roll": 177.11781311035156,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.6244890689849854,
"beacon_e_m": -4.9818010330200195,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:22.329 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 1056434760,
"ping_counter": 0,
"carrier_counter": 31690794,
"distance_m": 5.630833625793457,
"distance_unc": 0.0,
"azimuth_deg": 107.80000305175781,
"azimuth_unc": 0.0,
"elevation_deg": -47.10000228881836,
"elevation_unc": 0.0,
"snr": 17.71337127685547,
"beacon_x_m": -1.721319556236267,
"beacon_y_m": -5.361281871795654,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 132.2926788330078,
"usbl_pitch": -11.163581848144531,
"usbl_roll": 176.88021850585938,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.807525396347046,
"beacon_e_m": -4.880992412567139,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:23.319 | INFO | __main__:print_message:34 - printer:{
"id": 2,
"role": 2,
"reserved": 0,
"timestamp_us": 1057424760,
"ping_counter": 0,
"carrier_counter": 31720855,
"distance_m": 5.534167289733887,
"distance_unc": 0.0,
"azimuth_deg": 103.19999694824219,
"azimuth_unc": 0.0,
"elevation_deg": 3.0999982357025146,
"elevation_unc": 0.0,
"snr": 17.313335418701172,
"beacon_x_m": -1.263731837272644,
"beacon_y_m": -5.387948513031006,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 133.18313598632812,
"usbl_pitch": -10.87153434753418,
"usbl_roll": 176.30233764648438,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -3.0639193058013916,
"beacon_e_m": -4.608623027801514,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:24.341 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1058447837,
"ping_counter": 0,
"carrier_counter": 31750940,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 109.89999389648438,
"azimuth_unc": 0.0,
"elevation_deg": -23.200000762939453,
"elevation_unc": 0.0,
"snr": 17.326976776123047,
"beacon_x_m": -1.8261356353759766,
"beacon_y_m": -5.044646739959717,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 133.1935272216797,
"usbl_pitch": -11.217507362365723,
"usbl_roll": 176.8171844482422,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.427854537963867,
"beacon_e_m": -4.784219264984131,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:25.331 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1059437852,
"ping_counter": 0,
"carrier_counter": 31781029,
"distance_m": 5.34083366394043,
"distance_unc": 0.0,
"azimuth_deg": 70.0999984741211,
"azimuth_unc": 0.0,
"elevation_deg": -8.30000114440918,
"elevation_unc": 0.0,
"snr": 17.337350845336914,
"beacon_x_m": 1.8179104328155518,
"beacon_y_m": -5.021922588348389,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 133.51600646972656,
"usbl_pitch": -10.562745094299316,
"usbl_roll": 176.4199676513672,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -4.893543720245361,
"beacon_e_m": -2.139564037322998,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:26.355 | INFO | __main__:print_message:34 - printer:{
"id": 2,
"role": 2,
"reserved": 0,
"timestamp_us": 1060460837,
"ping_counter": 0,
"carrier_counter": 31811100,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": -126.30000305175781,
"azimuth_unc": 0.0,
"elevation_deg": -103.79999542236328,
"elevation_unc": 0.0,
"snr": 17.11989402770996,
"beacon_x_m": -3.1761515140533447,
"beacon_y_m": 4.323805332183838,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 133.55126953125,
"usbl_pitch": -11.149642944335938,
"usbl_roll": 176.79420471191406,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 5.322092533111572,
"beacon_e_m": 0.6771743297576904,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:27.346 | INFO | __main__:print_message:34 - printer:{
"id": 2,
"role": 2,
"reserved": 0,
"timestamp_us": 1061450851,
"ping_counter": 0,
"carrier_counter": 31841199,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 9.400007247924805,
"azimuth_unc": 0.0,
"elevation_deg": -52.30000686645508,
"elevation_unc": 0.0,
"snr": 17.328378677368164,
"beacon_x_m": 5.292960166931152,
"beacon_y_m": -0.8762445449829102,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 133.64111328125,
"usbl_pitch": -11.24309253692627,
"usbl_roll": 176.47857666015625,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -4.286996841430664,
"beacon_e_m": 3.225661516189575,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:28.335 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1062440710,
"ping_counter": 0,
"carrier_counter": 31871296,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 85.5,
"azimuth_unc": 0.0,
"elevation_deg": -53.30000305175781,
"elevation_unc": 0.0,
"snr": 17.491247177124023,
"beacon_x_m": 0.4209330379962921,
"beacon_y_m": -5.348462104797363,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 133.8328399658203,
"usbl_pitch": -10.47528076171875,
"usbl_roll": 176.80291748046875,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -4.149704933166504,
"beacon_e_m": -3.400467872619629,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:29.361 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1063466857,
"ping_counter": 0,
"carrier_counter": 31901368,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 115.5999984741211,
"azimuth_unc": 0.0,
"elevation_deg": -35.10000228881836,
"elevation_unc": 0.0,
"snr": 17.731340408325195,
"beacon_x_m": -2.3181397914886475,
"beacon_y_m": -4.838332653045654,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 134.13609313964844,
"usbl_pitch": -11.042613983154297,
"usbl_roll": 176.64231872558594,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -1.8581405878067017,
"beacon_e_m": -5.0329461097717285,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:30.347 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1064453786,
"ping_counter": 0,
"carrier_counter": 31931447,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 123.5,
"azimuth_unc": 0.0,
"elevation_deg": -11.30000114440918,
"elevation_unc": 0.0,
"snr": 17.847354888916016,
"beacon_x_m": -2.961142063140869,
"beacon_y_m": -4.4737982749938965,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 134.70327758789062,
"usbl_pitch": -10.788965225219727,
"usbl_roll": 176.43887329101562,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -1.0968208312988281,
"beacon_e_m": -5.251687049865723,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:31.337 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1065443760,
"ping_counter": 0,
"carrier_counter": 31961526,
"distance_m": 5.2925004959106445,
"distance_unc": 0.0,
"azimuth_deg": 104.0,
"azimuth_unc": 0.0,
"elevation_deg": 9.299997329711914,
"elevation_unc": 0.0,
"snr": 17.250953674316406,
"beacon_x_m": -1.2803716659545898,
"beacon_y_m": -5.135290622711182,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 134.85777282714844,
"usbl_pitch": -10.849724769592285,
"usbl_roll": 176.68118286132812,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.737091541290283,
"beacon_e_m": -4.529778480529785,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:33.353 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1067459836,
"ping_counter": 0,
"carrier_counter": 32021695,
"distance_m": 5.34083366394043,
"distance_unc": 0.0,
"azimuth_deg": 52.100006103515625,
"azimuth_unc": 0.0,
"elevation_deg": -59.30000305175781,
"elevation_unc": 0.0,
"snr": 17.164791107177734,
"beacon_x_m": 3.280794620513916,
"beacon_y_m": -4.214366912841797,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 134.5281219482422,
"usbl_pitch": -11.390545845031738,
"usbl_roll": 176.75497436523438,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -5.305136680603027,
"beacon_e_m": -0.6164636015892029,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:35.367 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1069472780,
"ping_counter": 0,
"carrier_counter": 32081875,
"distance_m": 5.268333911895752,
"distance_unc": 0.0,
"azimuth_deg": 101.9000015258789,
"azimuth_unc": 0.0,
"elevation_deg": -6.7000017166137695,
"elevation_unc": 0.0,
"snr": 17.408477783203125,
"beacon_x_m": -1.0863527059555054,
"beacon_y_m": -5.155111789703369,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 136.0665283203125,
"usbl_pitch": -10.824348449707031,
"usbl_roll": 176.63134765625,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.7944016456604004,
"beacon_e_m": -4.466168403625488,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:36.357 | INFO | __main__:print_message:34 - printer:{
"id": 255,
"role": 2,
"reserved": 0,
"timestamp_us": 1070462775,
"ping_counter": 0,
"carrier_counter": 32111946,
"distance_m": 5.655000686645508,
"distance_unc": 0.0,
"azimuth_deg": 117.19999694824219,
"azimuth_unc": 0.0,
"elevation_deg": -44.0,
"elevation_unc": 0.0,
"snr": 18.393396377563477,
"beacon_x_m": -2.584888458251953,
"beacon_y_m": -5.0296502113342285,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 136.0863800048828,
"usbl_pitch": -10.885085105895996,
"usbl_roll": 176.70150756835938,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -1.6263130903244019,
"beacon_e_m": -5.416100025177002,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:37.380 | INFO | __main__:print_message:34 - printer:{
"id": 1,
"role": 2,
"reserved": 0,
"timestamp_us": 1071485769,
"ping_counter": 0,
"carrier_counter": 32142019,
"distance_m": 5.316667079925537,
"distance_unc": 0.0,
"azimuth_deg": 104.69999694824219,
"azimuth_unc": 0.0,
"elevation_deg": 39.69999694824219,
"elevation_unc": 0.0,
"snr": 17.630970001220703,
"beacon_x_m": -1.3491462469100952,
"beacon_y_m": -5.142640590667725,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 136.13787841796875,
"usbl_pitch": -10.661099433898926,
"usbl_roll": 176.63031005859375,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -2.5907185077667236,
"beacon_e_m": -4.642749786376953,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:41.376 | INFO | __main__:print_message:34 - printer:{
"id": 8,
"role": 2,
"reserved": 0,
"timestamp_us": 1075481852,
"ping_counter": 0,
"carrier_counter": 32262362,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 27.19999885559082,
"azimuth_unc": 0.0,
"elevation_deg": 52.89999771118164,
"elevation_unc": 0.0,
"snr": 17.491342544555664,
"beacon_x_m": 4.771719455718994,
"beacon_y_m": -2.4523305892944336,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 137.14990234375,
"usbl_pitch": -10.538545608520508,
"usbl_roll": 176.85910034179688,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -5.166104316711426,
"beacon_e_m": 1.4472732543945312,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:44.380 | INFO | __main__:print_message:34 - printer:{
"id": 8,
"role": 2,
"reserved": 0,
"timestamp_us": 1078484776,
"ping_counter": 0,
"carrier_counter": 32352636,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 96.19998931884766,
"azimuth_unc": 0.0,
"elevation_deg": -44.80000305175781,
"elevation_unc": 0.0,
"snr": 17.237899780273438,
"beacon_x_m": -0.5794157385826111,
"beacon_y_m": -5.333621025085449,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 138.22242736816406,
"usbl_pitch": -10.573490142822266,
"usbl_roll": 176.5525360107422,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -3.12138295173645,
"beacon_e_m": -4.363508224487305,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:46.392 | INFO | __main__:print_message:34 - printer:{
"id": 8,
"role": 2,
"reserved": 0,
"timestamp_us": 1080497864,
"ping_counter": 0,
"carrier_counter": 32412783,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 72.30000305175781,
"azimuth_unc": 0.0,
"elevation_deg": -36.70000076293945,
"elevation_unc": 0.0,
"snr": 17.588912963867188,
"beacon_x_m": 1.6311371326446533,
"beacon_y_m": -5.111029624938965,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 138.55136108398438,
"usbl_pitch": -10.101583480834961,
"usbl_roll": 176.2457275390625,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": -4.605856418609619,
"beacon_e_m": -2.751239776611328,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:49.396 | INFO | __main__:print_message:34 - printer:{
"id": 8,
"role": 2,
"reserved": 0,
"timestamp_us": 1083501238,
"ping_counter": 0,
"carrier_counter": 32503017,
"distance_m": 5.3650007247924805,
"distance_unc": 0.0,
"azimuth_deg": 172.89999389648438,
"azimuth_unc": 0.0,
"elevation_deg": -11.900001525878906,
"elevation_unc": 0.0,
"snr": 17.99226951599121,
"beacon_x_m": -5.323861598968506,
"beacon_y_m": -0.6631224155426025,
"beacon_latitude": "nan",
"beacon_longitude": "nan",
"beacon_depth": 0.0,
"usbl_yaw": 138.96632385253906,
"usbl_pitch": -11.006739616394043,
"usbl_roll": 176.61827087402344,
"usbl_latitude": "nan",
"usbl_longitude": "nan",
"last_iTOW": 0,
"beacon_n_m": 3.5805747509002686,
"beacon_e_m": -3.9953370094299316,
"code_snr": [
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan",
"nan"
]
}
2026-03-22 08:49:50.179 | INFO | kogger_protocol_driver:_reader_thread_loop:568 - Reader thread finished.
2026-03-22 08:49:50.180 | INFO | kogger_protocol_driver:disconnect:352 - Serial port /dev/ttyAMA4 closed.
2026-03-22 08:49:50.181 | INFO | kogger_protocol_driver:disconnect:364 - Disconnected and cleaned up.

178
driver/test/test_auv.py Executable file
View File

@@ -0,0 +1,178 @@
#! /usr/bin/env python
# Test to run AUV. Will respond to all ping received and save the state received
import time
import sys
import json
from loguru import logger
import os
import datetime
# Add the parent directory to the Python path to find the driver module
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
try:
#from kogger_protocol_driver import KoggerSBPDevice, setup_logging
import kogger_protocol_driver
except ImportError:
logger.critical("Failed to import KoggerSBPDevice. Make sure kogger_protocol_driver.py is in the parent directory.")
sys.exit(1)
# --- Script Configuration ---
# Set the desired logging level: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
LOG_LEVEL = "INFO"
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
LOG_FILE = "log/"+str(timestamp)+"_log_auv.log"
# Default serial port if not provided via command line
#DEFAULT_SERIAL_PORT = "/dev/ttyUSB0"
DEFAULT_SERIAL_PORT = "/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0"
DEFAULT_SERIAL_PORT = "/dev/ttyAMA4"
DEFAULT_SERIAL_SPEED = 921600
response_received = -1
antenna = None
def print_message(message):
"""
This function is a callback that will be executed for each message
received from the antenna that is not a direct response to a command.
"""
parsed = json.loads(str(message).replace("nan", "'nan'").replace("'",'"'))
logger.info(json.dumps(parsed, indent=2))
try:
global response_received
response_received = message["id"]
logger.info("resp="+str(response_received))
except Exception as e:
logger.info("exception="+str(e))
pass
def test_callback(message):
global antenna
data=antenna.get_usbl_data()
global response_received
response_received = message["id"]
logger.info("test!!!!!!"+str(data))
return message
def check_all_getters(antenna):
"""
Calls all get_* methods on the antenna object and prints the results.
"""
print("\n--- Checking all getter methods ---")
# A list of all getter methods to call.
# Some methods require arguments, which are provided as tuples.
# (method_name, args_tuple)
getters_to_test = [
#('get_timestamp', ()),
#('get_distance', (0,)),
#('get_distance', (1,)),
#('get_chart_data', ()),
('get_attitude', (0,)), #!!OK
#('get_attitude', (1,)),
#('get_temperature', ()),
#('get_dataset_config', (0,)),
#('get_distance_setup', ()),
#('get_chart_setup', ()),
#('get_transceiver_settings', ()),
#('get_sound_speed', ()),
#('get_uart_config', (1, 0)), # uart_id=1, version=0
#('get_uart_config', (1, 1)), # uart_id=1, version=1
('get_version_info', ()), #!! OK
('get_mark_status', ()), #!! OK
#('get_diagnostics', ()),
#('get_navigation_data', ()),
#('get_dvl_velocity_data', ()),
#('get_signal_encoder_data', ()),
#('get_signal_decoder_data', ()),
#('get_auto_response_timeout', ()),
#('get_auto_response_filter', ()),
#('get_auto_response_payload', ()),
('get_usbl_solution', ()),
]
for method_name, args in getters_to_test:
try:
method = getattr(antenna, method_name)
print(f"Calling {method_name}{args}...")
result = method(*args)
print(f"Result: {result}")
except Exception as e:
print(f"An error occurred while calling {method_name}: {e}")
print("-" * 20)
time.sleep(0.01) # Give the device a moment between commands
print("--- Finished checking all getter methods ---\n")
def main():
"""
Main function to connect to the Kogger antenna and listen for messages.
"""
# Determine the serial port to use
if len(sys.argv) > 1:
serial_port = sys.argv[1]
else:
serial_port = DEFAULT_SERIAL_PORT
print(f"No serial port provided. Using default: {serial_port}")
# Instantiate the driver
global antenna
antenna = kogger_protocol_driver.KoggerSBPDevice(serial_port, DEFAULT_SERIAL_SPEED, default_timeout=0.02, log_level=LOG_LEVEL, log_file=LOG_FILE)
try:
# Connect to the antenna
if not antenna.connect():
print(f"Failed to connect to the antenna on port {serial_port}", file=sys.stderr)
sys.exit(1)
print(f"Successfully connected to the antenna on {serial_port}.")
# Perform a one-time check of all getter functions
check_all_getters(antenna)
result = antenna.set_auto_response_filter(0)
logger.info("set_auto_response_filter(0)="+str(result))
result = antenna.set_auto_response_timeout(0xffffffff)
logger.info("set_auto_response_timeout(0xffffffff)="+str(result))
result = antenna.set_auto_response_payload(0xff)
logger.info("set_auto_response_payload(0xff)="+str(result))
antenna.register_precallback(kogger_protocol_driver.ID_USBL_SOLUTION, antenna.callback_usbl_solution)
antenna.register_callback(kogger_protocol_driver.ID_USBL_SOLUTION, test_callback)
antenna.register_default_callback(print_message)
response_received_old = -1
global response_received
while True:
logger.info("response_received="+str(response_received))
if response_received_old != response_received:
response_received_old = response_received
try:
result = antenna.set_auto_response_payload(response_received)
except:
result = antenna.set_auto_response_payload(0xff)
logger.info("antenna.set_auto_response_payload("+str(response_received)+")="+str(result))
time.sleep(1)
for i in range(10000):
#result = antenna.send_acoustic_ping(i%9)
result = antenna.send_acoustic_ping(0)
print("sent "+str(i%9)+"result="+str(result))
time.sleep(1)
exit()
except KeyboardInterrupt:
print("\nExiting...")
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(f"type={exc_type}, fname={fname}, line={exc_tb.tb_lineno}")
finally:
# Ensure the connection is closed gracefully
print("Disconnecting from the antenna.")
antenna.disconnect()
if __name__ == "__main__":
main()

252
driver/test/test_kogger_driver.py Executable file
View File

@@ -0,0 +1,252 @@
#! /usr/bin/env python
import os
import sys
import time
import io # For BytesIO to simulate file reading for the mock
from loguru import logger
import threading
# Ensure the kogger_protocol_driver.py is in the Python path
# If it's in the same directory, this is usually fine.
# Otherwise, you might need to adjust sys.path:
# sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) # If driver is one dir up
try:
from kogger_protocol_driver import KoggerSBPDevice, ID_TIMESTAMP, ID_ATTITUDE, ID_UART, ID_FLASH, RESP_OK, RESP_ERR_KEY
except ImportError:
logger.critical("Failed to import KoggerSBPDevice. Make sure kogger_protocol_driver.py is in the same directory or Python path.")
sys.exit(1)
# --- Loguru Setup for the test script ---
logger.remove()
logger.add(sys.stderr, level="DEBUG", format="<white>{time:YYYY-MM-DD HH:mm:ss.SSS}</white> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>")
# --- Content for test_messages.bin ---
# Frame 1: Timestamp response (12345 ms)
frame1_ts_resp = b'\xBB\x55\x00\x01\x01\x04\x39\x30\x00\x00\x49\x95'
# Frame 2: Unsolicited Attitude data
frame2_att_unsol = b'\xBB\x55\x00\x01\x04\x06\xE8\x03\xF4\x01\x38\xFF\xC8\x28'
# Frame 3: RESP_OK to a hypothetical SET_UART_CONFIG command (ID 0x18), orig_chk A0B0
frame3_uart_resp_ok = b'\xBB\x55\x00\x81\x18\x03\x01\xA0\xB0\x2D\x24'
# Frame 4: RESP_ERR_KEY to a hypothetical SAVE_SETTINGS_TO_FLASH command (ID 0x23), orig_chk C1D1
frame4_flash_resp_err = b'\xBB\x55\x00\x81\x23\x03\x07\xC1\xD1\xB0\x0D'
# Frame 5: Another unsolicited Timestamp (67890 ms)
frame5_ts_unsol = b'\xBB\x55\x00\x01\x01\x04\x32\x09\x01\x00\x42\xCD'
# Concatenate frames to simulate the binary file content
TEST_BINARY_DATA = frame1_ts_resp + frame2_att_unsol + frame3_uart_resp_ok + frame4_flash_resp_err + frame5_ts_unsol
TEST_BINARY_FILE_PATH = "test_messages.bin"
class MockSerial:
"""
A mock serial port that reads from a predefined byte stream (simulating a file)
and logs data written to it.
"""
def __init__(self, port, baudrate, timeout=0.1, binary_data=b""):
self.port = port
self.baudrate = baudrate
self.timeout = timeout # Read timeout
self._is_open = False
self.binary_stream = io.BytesIO(binary_data) # Use BytesIO to simulate file reading
self.written_data = bytearray() # To capture data written by the driver
# For KoggerSBPDevice, serial_read_timeout is passed to its __init__
# and used for its internal serial.Serial object.
# Our mock uses its own 'timeout' for its 'read' method.
# The driver's serial_read_timeout on KoggerSBPDevice will configure the *real* serial port
# if it were used. Here, it's less critical for the mock itself, but good to have.
logger.info(f"MockSerial initialized for port '{port}' at {baudrate} baud with {len(binary_data)} bytes of test data.")
def open(self):
self._is_open = True
logger.info(f"MockSerial port {self.port} opened.")
def close(self):
self._is_open = False
logger.info(f"MockSerial port {self.port} closed.")
self.binary_stream.close()
@property
def is_open(self):
return self._is_open
@property
def in_waiting(self):
if not self._is_open:
return 0
current_pos = self.binary_stream.tell()
# Get the total number of bytes in the stream buffer
# For BytesIO, getbuffer().nbytes gives total size
total_size = self.binary_stream.getbuffer().nbytes
return total_size - current_pos
def read(self, size=1):
if not self._is_open:
raise serial.SerialException("Port not open")
# Simulate timeout behavior: if no data, return empty bytes after timeout
# For this mock, if we reach EOF, read() returns b''.
# The driver's reader thread has its own loop and small reads.
data = self.binary_stream.read(size)
if data:
logger.debug(f"MockSerial: read {len(data)} bytes: {data.hex().upper()}")
# else:
# logger.debug(f"MockSerial: read attempt, no data (EOF or simulated timeout)")
return data
def write(self, data):
if not self.is_open:
raise serial.SerialException("Port not open")
logger.info(f"MockSerial: driver wrote {len(data)} bytes: {data.hex().upper()}")
self.written_data.extend(data)
return len(data)
def reset_input_buffer(self):
logger.info("MockSerial: reset_input_buffer called (clearing mock written_data for this example).")
# In a real scenario, this clears hardware buffers. Here, it's less meaningful
# unless the driver specifically expects some state change.
# The driver's internal _receive_buffer will still exist.
def reset_output_buffer(self):
logger.info("MockSerial: reset_output_buffer called.")
# Clears OS transmit buffer. No direct equivalent for simple mock.
# --- Test Callbacks ---
received_unsolicited_attitude = None
received_unsolicited_timestamps = []
def attitude_callback(frame):
global received_unsolicited_attitude
logger.success(f"[ATTITUDE CALLBACK] Received frame ID: {frame['id']:#02x}")
if frame['id'] == ID_ATTITUDE and frame.get('checksum_ok'):
payload = frame['payload']
yaw, pitch, roll = struct.unpack('<hhh', payload)
received_unsolicited_attitude = {'yaw_deg': yaw / 100.0, 'pitch_deg': pitch / 100.0, 'roll_deg': roll / 100.0}
logger.info(f" Attitude data: {received_unsolicited_attitude}")
def timestamp_callback(frame):
global received_unsolicited_timestamps
logger.success(f"[TIMESTAMP CALLBACK] Received frame ID: {frame['id']:#02x}")
if frame['id'] == ID_TIMESTAMP and frame.get('checksum_ok'):
payload = frame['payload']
timestamp = struct.unpack('<I', payload)[0]
received_unsolicited_timestamps.append(timestamp)
logger.info(f" Timestamp data: {timestamp} ms")
def run_tests():
global received_unsolicited_attitude, received_unsolicited_timestamps
received_unsolicited_attitude = None # Reset for test
received_unsolicited_timestamps = [] # Reset for test
# Create the test binary file (optional, can use BytesIO directly)
# For this test, we'll pass the bytes directly to MockSerial
# with open(TEST_BINARY_FILE_PATH, "wb") as f:
# f.write(TEST_BINARY_DATA)
# logger.info(f"Created test data file: {TEST_BINARY_FILE_PATH}")
# Instantiate the mock serial port with our predefined binary data
mock_port = MockSerial(port='loop://test', baudrate=115200, binary_data=TEST_BINARY_DATA)
# Instantiate the driver with the mock port
# The 'serial_read_timeout' in KoggerSBPDevice is for its internal serial.Serial object.
# Our MockSerial uses its own timeout if we were to implement blocking reads with timeout.
# For this stream-based mock, the driver's reader thread will consume data as it becomes available.
driver = KoggerSBPDevice(port=None, baudrate=115200, default_timeout=1.0) # Pass None for port
driver.serial_conn = mock_port # Manually assign the mock serial connection
driver.serial_conn.open() # Open the mock port
# Start the driver's reader thread (normally connect() does this)
driver._stop_event.clear()
driver._reader_thread = threading.Thread(target=driver._reader_thread_loop, daemon=True)
driver._reader_thread.start()
logger.info("Manually started driver's reader thread with mock port.")
# Register callbacks
driver.register_callback(ID_ATTITUDE, attitude_callback)
driver.register_callback(ID_TIMESTAMP, timestamp_callback) # Will catch solicited and unsolicited if not handled by _execute_command first
# --- Test Case 1: Get Timestamp (expects frame1_ts_resp) ---
logger.info("\n--- Test 1: driver.get_timestamp() ---")
ts_data = driver.get_timestamp()
if ts_data and ts_data['timestamp_ms'] == 12345:
logger.success(f" PASS: get_timestamp() returned {ts_data}")
else:
logger.error(f" FAIL: get_timestamp() returned {ts_data}, expected 12345 ms.")
time.sleep(0.2) # Allow reader thread to process next items if any
# --- Test Case 2: Check for Unsolicited Attitude (expects frame2_att_unsol via callback) ---
logger.info("\n--- Test 2: Check for unsolicited Attitude message ---")
# The attitude message should have been processed by the reader thread and callback by now.
time.sleep(0.5) # Give callbacks time to fire from reader thread
if received_unsolicited_attitude:
logger.success(f" PASS: Unsolicited attitude received: {received_unsolicited_attitude}")
# Expected: {'yaw_deg': 10.0, 'pitch_deg': 5.0, 'roll_deg': -2.0}
if abs(received_unsolicited_attitude['yaw_deg'] - 10.0) < 0.01 and \
abs(received_unsolicited_attitude['pitch_deg'] - 5.0) < 0.01 and \
abs(received_unsolicited_attitude['roll_deg'] - (-2.0)) < 0.01:
logger.success(" Attitude data is correct.")
else:
logger.error(f" Attitude data INCORRECT: {received_unsolicited_attitude}")
else:
logger.error(" FAIL: Unsolicited attitude NOT received via callback.")
# --- Test Case 3: Set UART Config (expects frame3_uart_resp_ok) ---
# This is a SET command, it expects a RESP_OK.
# The mock doesn't check the "sent" command's checksum, but a real device would.
# Our frame3_uart_resp_ok assumes the original command had checksum A0B0.
logger.info("\n--- Test 3: driver.set_uart_config() ---")
# We are not actually changing baudrate here, just testing the command flow
# For the mock, uart_id, baudrate values don't affect the response source
success_uart = driver.set_uart_config(uart_id=1, baudrate=9600)
if success_uart:
logger.success(" PASS: set_uart_config reported success (RESP_OK received).")
else:
logger.error(" FAIL: set_uart_config reported failure.")
time.sleep(0.2)
# --- Test Case 4: Save Settings (expects frame4_flash_resp_err) ---
# This command will receive a RESP_ERR_KEY from our test data
logger.info("\n--- Test 4: driver.save_settings_to_flash() - expecting error ---")
success_flash = driver.save_settings_to_flash()
if not success_flash: # Expecting False due to RESP_ERR_KEY
# The driver's _execute_command should log the warning about the RESP_ERR_KEY.
# We can also check the specific response if _execute_command returned the error frame.
# The current save_settings_to_flash returns True only on RESP_OK.
logger.success(" PASS: save_settings_to_flash correctly reported failure (as expected due to RESP_ERR_KEY in test data).")
else:
logger.error(" FAIL: save_settings_to_flash reported success, but an error was expected.")
time.sleep(0.2)
# --- Test Case 5: Check for second Unsolicited Timestamp (expects frame5_ts_unsol via callback) ---
logger.info("\n--- Test 5: Check for second unsolicited Timestamp message ---")
time.sleep(0.5) # Give callbacks time to fire
if len(received_unsolicited_timestamps) > 0 and 67890 in received_unsolicited_timestamps:
logger.success(f" PASS: Second unsolicited timestamp (67890ms) received: {received_unsolicited_timestamps}")
elif len(received_unsolicited_timestamps) > 0 :
logger.warning(f" WARN: Unsolicited timestamp(s) received, but 67890ms not found. Got: {received_unsolicited_timestamps}")
else:
logger.error(" FAIL: Second unsolicited timestamp (67890ms) NOT received via callback.")
# --- Check remaining data in mock port ---
remaining_bytes = mock_port.in_waiting
if remaining_bytes == 0:
logger.success(f"\n--- All test data consumed from mock port. ---")
else:
logger.warning(f"\n--- {remaining_bytes} bytes remaining in mock port's data stream. ---")
logger.debug(f"Remaining data: {mock_port.read(remaining_bytes).hex().upper()}")
# Cleanup
logger.info("Stopping driver and closing mock port...")
driver.disconnect() # This will stop the thread and close the mock port
# if os.path.exists(TEST_BINARY_FILE_PATH):
# os.remove(TEST_BINARY_FILE_PATH)
# logger.info(f"Removed test data file: {TEST_BINARY_FILE_PATH}")
if __name__ == "__main__":
run_tests()
logger.info("Test script finished.")

View File

@@ -0,0 +1,16 @@
# This would be written to test_messages.bin by the test script,
# or you can create the file with these exact bytes.
# For clarity, showing how it's constructed:
# Frame 1: Timestamp response (12345 ms)
frame1 = b'\xBB\x55\x00\x01\x01\x04\x39\x30\x00\x00\x49\x95'
# Frame 2: Unsolicited Attitude data
frame2 = b'\xBB\x55\x00\x01\x04\x06\xE8\x03\xF4\x01\x38\xFF\xC8\x28'
# Frame 3: RESP_OK to a SET_UART_CONFIG command (ID 0x18)
frame3 = b'\xBB\x55\x00\x81\x18\x03\x01\xA0\xB0\x2D\x24'
# Frame 4: RESP_ERR_KEY to a SAVE_SETTINGS_TO_FLASH command (ID 0x23)
frame4 = b'\xBB\x55\x00\x81\x23\x03\x07\xC1\xD1\xB0\x0D'
# Frame 5: Another unsolicited Timestamp (67890 ms)
frame5 = b'\xBB\x55\x00\x01\x01\x04\x32\x09\x01\x00\x42\xCD'
binary_file_content = frame1 + frame2 + frame3 + frame4 + frame5

230
driver/test/test_multi_antenna.py Executable file
View File

@@ -0,0 +1,230 @@
#! /usr/bin/env python
# Test to run multi antenna.
# arg 1 is the USB number
# arg 2 is the index slot
# arg 3 is the total slot
import time
import sys
import tty
import termios
import select
import json
import os
from loguru import logger
import datetime
# Add the parent directory to the Python path to find the driver module
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
try:
#from kogger_protocol_driver import KoggerSBPDevice, setup_logging
import kogger_protocol_driver
except ImportError:
logger.critical("Failed to import KoggerSBPDevice. Make sure kogger_protocol_driver.py is in the parent directory.")
sys.exit(1)
# --- Script Configuration ---
# Set the desired logging level: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
LOG_LEVEL = "INFO"
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
LOG_FILE = "log/"+str(timestamp)+"_log_usv.log"
# Default serial port if not provided via command line
DEFAULT_SERIAL_PORT = "/dev/ttyUSB0"
#DEFAULT_SERIAL_PORT = "/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0"
DEFAULT_SERIAL_SPEED = 921600
antenna = None
def print_message(message):
"""
This function is a callback that will be executed for each message
received from the antenna that is not a direct response to a command.
"""
parsed = json.loads(str(message).replace("nan", "'nan'").replace("'",'"'))
logger.info("printer:"+json.dumps(parsed, indent=2))
def test_callback(message):
global antenna
data=antenna.get_usbl_data()
global response_received
response_received = message["id"]
logger.info("test!!!!!!"+str(data))
return message
def is_data():
"""
Checks if there is data to be read from stdin.
"""
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
def check_all_getters(antenna):
"""
Calls all get_* methods on the antenna object and prints the results.
"""
print("\n--- Checking all getter methods ---")
# A list of all getter methods to call.
# Some methods require arguments, which are provided as tuples.
# (method_name, args_tuple)
getters_to_test = [
#('get_timestamp', ()),
#('get_distance', (0,)),
#('get_distance', (1,)),
#('get_chart_data', ()),
#('get_attitude', (0,)), #!!OK
#('get_attitude', (1,)),
#('get_temperature', ()),
#('get_dataset_config', (0,)),
#('get_distance_setup', ()),
#('get_chart_setup', ()),
#('get_transceiver_settings', ()),
#('get_sound_speed', ()),
#('get_uart_config', (1, 0)), # uart_id=1, version=0
#('get_uart_config', (1, 1)), # uart_id=1, version=1
('get_version_info', ()), #!! OK
#('get_mark_status', ()), #!! OK
#('get_diagnostics', ()),
#('get_navigation_data', ()),
#('get_dvl_velocity_data', ()),
#('get_signal_encoder_data', ()),
#('get_signal_decoder_data', ()),
#('get_auto_response_timeout', ()),
#('get_auto_response_filter', ()),
#('get_auto_response_payload', ()),
#('get_usbl_solution', ()),
]
for method_name, args in getters_to_test:
try:
method = getattr(antenna, method_name)
print(f"Calling {method_name}{args}...")
result = method(*args)
print(f"Result: {result}")
except Exception as e:
print(f"An error occurred while calling {method_name}: {e}")
print("-" * 20)
time.sleep(0.01) # Give the device a moment between commands
print("--- Finished checking all getter methods ---\n")
def main():
"""
Main function to connect to the Kogger antenna and listen for messages.
"""
# Determine the serial port to use
slot_total = 0
if len(sys.argv)>1:
if sys.argv[1].startswith("/dev/"):
DEFAULT_SERIAL_PORT = sys.argv[1]
serial_port = sys.argv[1]
slot_index = int(sys.argv[2])
slot_total = int(sys.argv[3])
slot_duration = 1
else:
serial_port = "/dev/ttyUSB"+str(sys.argv[1])
slot_index = 0
slot_total = 0
slot_duration = 1
else:
serial_port = DEFAULT_SERIAL_PORT
print(f"No serial port provided. Using default: {serial_port}")
# Instantiate the driver
global antenna
antenna = kogger_protocol_driver.KoggerSBPDevice(serial_port, DEFAULT_SERIAL_SPEED, default_timeout=0.02, log_level=LOG_LEVEL, log_file=LOG_FILE)
try:
# Connect to the antenna
if not antenna.connect():
print(f"Failed to connect to the antenna on port {serial_port}", file=sys.stderr)
sys.exit(1)
print(f"Successfully connected to the antenna on {serial_port}.")
# Perform a one-time check of all getter functions
check_all_getters(antenna)
result = antenna.set_auto_response_filter(0)
logger.info("set_auto_response_filter(0)="+str(result))
result = antenna.set_auto_response_timeout(0xffffffff)
logger.info("set_auto_response_timeout(0xffffffff)="+str(result))
result = antenna.set_auto_response_payload(0xff)
logger.info("set_auto_response_payload(0xff)="+str(result))
if slot_index!=0:
result = antenna.set_echo_filter(True)
logger.info("set_echo_filter(True)="+str(result))
else:
result = antenna.set_echo_filter(False)
logger.info("set_echo_filter(False)="+str(result))
if slot_total!=0:
if slot_index!=0:
enable_delay=True
else:
enable_delay=False
result = antenna.set_sync_mode(slot_total, slot_index, slot_duration, enable_delay)
logger.info(f"set_sync_mode({slot_total},{slot_index},{slot_duration},{enable_delay})={result}")
if slot_index !=0:
antenna.register_precallback(kogger_protocol_driver.ID_USBL_SOLUTION, antenna.callback_usbl_solution)
antenna.register_callback(kogger_protocol_driver.ID_USBL_SOLUTION, test_callback)
antenna.register_default_callback(print_message)
print("\nPress a number (0-9) to send an acoustic ping. Press 'q' to quit.")
data_number = 255
last_ping_time = 0
str_star_moving_ping = ['|','/','','\\']
cnt_star_moving_ping = 0
str_star = ""
while True:
# Handle keyboard input
if is_data():
char = sys.stdin.read(1)
if char.isdigit():
data_number = int(char)
print(f"\r\n--> Switched data number to: {data_number}")
if slot_index==0:
result = antenna.set_auto_response_payload(data_number)
elif char.lower() == 'q':
print("\r\nQuitting...")
break
elif ord(char) == 3: # Ctrl+C
raise KeyboardInterrupt
# Send ping every 1 second
current_time = time.time()
if current_time - last_ping_time >= 1:
last_ping_time = current_time
if slot_index!=0:
result = antenna.send_acoustic_ping(data_number)
if result == True:
cnt_star_moving_ping = (cnt_star_moving_ping+1)%4
str_star = str_star_moving_ping[cnt_star_moving_ping]
else:
str_star = "!"
# Update the prompt on the same line
prompt = f"\r"+str_star+"--> Pinging with "+str(data_number)+". Press 0-9+ENTER to change, 'q'+ENTER to quit."
sys.stdout.write(prompt)
sys.stdout.flush()
time.sleep(0.1)
except KeyboardInterrupt:
print("\nExiting...")
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(f"type={exc_type}, fname={fname}, line={exc_tb.tb_lineno}")
finally:
# Ensure the connection is closed gracefully
print("Disconnecting from the antenna.")
antenna.disconnect()
if __name__ == "__main__":
main()

183
driver/test/test_usv.py Executable file
View File

@@ -0,0 +1,183 @@
#! /usr/bin/env python
# Test to run USV. Will ping AUV, and wait for response.
import time
import sys
import tty
import termios
import select
import json
import os
from loguru import logger
import datetime
# Add the parent directory to the Python path to find the driver module
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from kogger_protocol_driver import KoggerSBPDevice
# --- Script Configuration ---
# Set the desired logging level: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
LOG_LEVEL = "INFO"
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
LOG_FILE = "log/"+str(timestamp)+"_log_usv.log"
# Default serial port if not provided via command line
DEFAULT_SERIAL_PORT = "/dev/ttyAMA4"
#DEFAULT_SERIAL_PORT = "/dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3:1.0"
DEFAULT_SERIAL_SPEED = 921600
def print_message(message):
"""
This function is a callback that will be executed for each message
received from the antenna that is not a direct response to a command.
"""
parsed = json.loads(str(message).replace("nan", "'nan'").replace("'",'"'))
logger.info("printer:"+json.dumps(parsed, indent=2))
def is_data():
"""
Checks if there is data to be read from stdin.
"""
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])
def check_all_getters(antenna):
"""
Calls all get_* methods on the antenna object and prints the results.
"""
print("\n--- Checking all getter methods ---")
# A list of all getter methods to call.
# Some methods require arguments, which are provided as tuples.
# (method_name, args_tuple)
getters_to_test = [
#('get_timestamp', ()),
#('get_distance', (0,)),
#('get_distance', (1,)),
#('get_chart_data', ()),
#('get_attitude', (0,)), #!!OK
#('get_attitude', (1,)),
#('get_temperature', ()),
#('get_dataset_config', (0,)),
#('get_distance_setup', ()),
#('get_chart_setup', ()),
#('get_transceiver_settings', ()),
#('get_sound_speed', ()),
#('get_uart_config', (1, 0)), # uart_id=1, version=0
#('get_uart_config', (1, 1)), # uart_id=1, version=1
('get_version_info', ()), #!! OK
#('get_mark_status', ()), #!! OK
#('get_diagnostics', ()),
#('get_navigation_data', ()),
#('get_dvl_velocity_data', ()),
#('get_signal_encoder_data', ()),
#('get_signal_decoder_data', ()),
#('get_auto_response_timeout', ()),
#('get_auto_response_filter', ()),
#('get_auto_response_payload', ()),
#('get_usbl_solution', ()),
]
for method_name, args in getters_to_test:
try:
method = getattr(antenna, method_name)
print(f"Calling {method_name}{args}...")
result = method(*args)
print(f"Result: {result}")
except Exception as e:
print(f"An error occurred while calling {method_name}: {e}")
print("-" * 20)
time.sleep(0.01) # Give the device a moment between commands
print("--- Finished checking all getter methods ---\n")
def main():
"""
Main function to connect to the Kogger antenna and listen for messages.
"""
global DEFAULT_SERIAL_PORT
global DEFAULT_SERIAL_SPEED
global LOG_LEVEL
global LOG_FILE
# Determine the serial port to use
if len(sys.argv)>1:
if sys.argv[1].startswith("/dev/"):
DEFAULT_SERIAL_PORT = sys.argv[1]
serial_port = sys.argv[1]
else:
serial_port = "/dev/ttyUSB"+str(sys.argv[1])
else:
print(DEFAULT_SERIAL_PORT)
serial_port = DEFAULT_SERIAL_PORT
print(f"No serial port provided. Using default: {serial_port}")
# Instantiate the driver
antenna = KoggerSBPDevice(serial_port, DEFAULT_SERIAL_SPEED, default_timeout=0.02, log_level=LOG_LEVEL, log_file=LOG_FILE)
try:
# Connect to the antenna
if not antenna.connect():
print(f"Failed to connect to the antenna on port {serial_port}", file=sys.stderr)
sys.exit(1)
print(f"Successfully connected to the antenna on {serial_port}.")
# Perform a one-time check of all getter functions
check_all_getters(antenna)
result = antenna.set_auto_response_filter(0)
logger.info("set_auto_response_filter(0)="+str(result))
result = antenna.set_auto_response_timeout(0xffffffff)
logger.info("set_auto_response_timeout(0xffffffff)="+str(result))
result = antenna.set_auto_response_payload(0xff)
logger.info("set_auto_response_payload(0xff)="+str(result))
antenna.register_default_callback(print_message)
print("\nPress a number (0-9) to send an acoustic ping. Press 'q' to quit.")
data_number = 255
last_ping_time = 0
str_star_moving_ping = ['|','/','','\\']
cnt_star_moving_ping = 0
str_star = ""
while True:
# Handle keyboard input
if is_data():
char = sys.stdin.read(1)
if char.isdigit():
data_number = int(char)
print(f"\r\n--> Switched data number to: {data_number}")
elif char.lower() == 'q':
print("\r\nQuitting...")
break
elif ord(char) == 3: # Ctrl+C
raise KeyboardInterrupt
# Send ping every 1 second
current_time = time.time()
if current_time - last_ping_time >= 1:
last_ping_time = current_time
result = antenna.send_acoustic_ping(data_number)
if result == True:
cnt_star_moving_ping = (cnt_star_moving_ping+1)%4
str_star = str_star_moving_ping[cnt_star_moving_ping]
else:
str_star = "!"
# Update the prompt on the same line
prompt = f"\r"+str_star+"--> Pinging with "+str(data_number)+". Press 0-9+ENTER to change, 'q'+ENTER to quit."
sys.stdout.write(prompt)
sys.stdout.flush()
time.sleep(0.1)
except KeyboardInterrupt:
print("\nExiting...")
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
finally:
# Ensure the connection is closed gracefully
print("Disconnecting from the antenna.")
antenna.disconnect()
if __name__ == "__main__":
main()

79
examples/auv_slave.py Normal file
View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python3
"""
Exemple : un AUV slave Kogger en mode transpondeur continu.
Le master USV envoie des pings adressés. Cet AUV répond automatiquement, logge
chaque ping reçu (timestamp, SNR, distance hardware), et publie en parallèle
sur stdout. Aucun arming par ping requis.
Lancement :
python3 auv_slave.py --port /dev/ttyUSB0 --address 2 --vehicle AUV-2
Pour intégrer dans un nœud ROS2 / NATS / MQTT, remplacer `on_ping` ci-dessous
par un publisher.
"""
import argparse
import time
import sys
sys.path.insert(0, "..") # rend transponder_continu.py importable depuis examples/
from transponder_continu import ContinuousTransponder, SyncSlot
def main():
p = argparse.ArgumentParser()
p.add_argument("--port", required=True)
p.add_argument("--address", type=int, required=True)
p.add_argument("--vehicle", default="AUV")
p.add_argument("--slot-total", type=int, default=0,
help="Si >0 : enrôle l'AUV dans un slot TDMA partagé.")
p.add_argument("--slot-duration", type=float, default=2.0)
args = p.parse_args()
sync = None
if args.slot_total > 0:
sync = SyncSlot(
slot_total=args.slot_total,
slot_index=args.address - 1, # convention : slot index = address - 1
slot_duration=args.slot_duration,
)
t = ContinuousTransponder(
port=args.port,
my_address=args.address,
vehicle_name=args.vehicle,
sync=sync,
watchdog_timeout_s=15.0, # re-arm si silence > 15 s (USV down ?)
)
pings_log = []
def on_ping(msg):
rec = {
"t_local": time.time(),
"id": msg.get("id"),
"snr": msg.get("snr"),
"distance_m": t.state.last_distance_m,
"raw": msg,
}
pings_log.append(rec)
print(
f"[{rec['t_local']:.3f}] ping #{t.state.pings_received} "
f"id={rec['id']} snr={rec['snr']} "
f"d={rec['distance_m']:.2f}m" if rec['distance_m'] else "d=—"
)
t.on_ping_received(on_ping)
print(f"=== {args.vehicle} en transpondeur continu, address={args.address} ===")
t.start()
try:
t.run_forever()
finally:
t.stop()
print(f"\nFin de session. {len(pings_log)} pings reçus au total.")
if __name__ == "__main__":
main()

302
transponder_continu.py Normal file
View File

@@ -0,0 +1,302 @@
#!/usr/bin/env python3
"""
Kogger USBL — mode transpondeur continu.
Wrapper de haut niveau autour de `kogger_protocol_driver.KoggerSBPDevice` qui
configure l'antenne acoustique Kogger comme un *slave transpondeur permanent* :
elle écoute en continu les pings adressés à son ID, répond automatiquement
(turnaround géré côté hardware Kogger), ignore les pings destinés aux autres,
et expose un callback Python pour chaque ping reçu.
Pas de re-armement par ping. Pas de boucle d'interrogation. Une seule init,
puis le device répond tant que le process tourne.
Usage minimal :
from transponder_continu import ContinuousTransponder
t = ContinuousTransponder(port="/dev/ttyUSB0", my_address=2,
vehicle_name="AUV-2")
t.on_ping_received(lambda solution: print("ping →", solution))
t.start()
try:
t.run_forever() # bloque le main thread
finally:
t.stop()
CLI :
python3 transponder_continu.py --port /dev/ttyUSB0 --address 2
Conception :
- Aucune modification du driver Kogger d'origine.
- N'utilise que des méthodes publiques déjà présentes (`set_usbl_transponder`,
`set_usbl_request_address_filter`, `set_usbl_monitor_config`, `set_sync_mode`,
`register_callback`, `set_auto_response_filter`).
- Compose les bons appels dans le bon ordre, en exposant une API "1-shot config".
- Watchdog optionnel : ré-applique la config si le device a rebooté (détecté
par perte de réponse > `watchdog_timeout_s`).
Auteur : Poulpe (2026-04-27) pour Flag.
Licence : même que driver upstream (cosma-tech/kogger_acousticAntenna).
"""
from __future__ import annotations
import argparse
import sys
import threading
import time
from dataclasses import dataclass, field
from typing import Callable, Optional
# Le driver upstream est attendu adjacent (cf. README pour le clone).
sys.path.insert(0, "driver")
from kogger_protocol_driver import KoggerSBPDevice, ID_USBL_SOLUTION, ID_DIST
@dataclass
class SyncSlot:
"""Configuration TDMA optionnelle si plusieurs slaves se partagent le canal."""
slot_total: int # nombre total de slots dans un cycle
slot_index: int # mon index de slot (0-indexed)
slot_duration: float # durée d'un slot en secondes
@dataclass
class TransponderState:
last_ping_at: float = 0.0
last_distance_m: Optional[float] = None
last_snr: Optional[float] = None
last_ping_id: Optional[int] = None
pings_received: int = 0
class ContinuousTransponder:
"""
Configure une antenne Kogger en transpondeur permanent sur une adresse donnée.
Args
----
port : port série (ex. "/dev/ttyUSB0")
my_address : ID de cette antenne, 1..7 (0 = promiscuous)
baudrate : baudrate UART, défaut 921600 (recommandé Kogger)
vehicle_name : étiquette utilisée dans les logs CSV
echo_filter_us : suppression des échos en µs, défaut 400 ms
sync : SyncSlot ou None. Si fourni, le device attend son slot.
watchdog_timeout_s: si > 0, ré-applique la config en cas de silence prolongé.
Notes
-----
Adresse Kogger autorisées en transpondeur : 1..7. La valeur 0 est promiscuous
(répond à tous), généralement à éviter en multi-AUV. La valeur 0xFF =
"slot désactivé" dans le filtre 8-byte.
Côté master : envoyez `set_usbl_ping_request_direct(address=N, cmd_id=K, ...)`
où N est l'adresse de ce transpondeur. Le hardware Kogger gère automatiquement
le pong (turnaround_B) — vous n'avez rien à faire côté slave une fois `start()`
appelé.
"""
def __init__(
self,
port: str,
my_address: int,
baudrate: int = 921600,
vehicle_name: Optional[str] = None,
echo_filter_us: int = 400_000,
sync: Optional[SyncSlot] = None,
watchdog_timeout_s: float = 0.0,
log_level: str = "INFO",
log_file: str = "",
):
if not 1 <= my_address <= 7:
raise ValueError(f"my_address must be 1..7, got {my_address}")
self._device = KoggerSBPDevice(
port=port,
baudrate=baudrate,
device_address=my_address,
vehicleName=vehicle_name,
log_level=log_level,
log_file=log_file,
)
self._my_address = my_address
self._echo_filter_us = echo_filter_us
self._sync = sync
self._watchdog_timeout_s = watchdog_timeout_s
self.state = TransponderState()
self._on_ping: Optional[Callable] = None
self._on_distance: Optional[Callable] = None
self._stop_event = threading.Event()
self._watchdog_thread: Optional[threading.Thread] = None
# ------------------------------------------------------------------ public
def on_ping_received(self, fn: Callable[[dict], None]) -> None:
"""Callback (message: dict) appelé pour chaque USBL_SOLUTION reçu."""
self._on_ping = fn
def on_distance(self, fn: Callable[[dict], None]) -> None:
"""Callback (message: dict) appelé pour chaque ID_DIST reçu."""
self._on_distance = fn
def start(self) -> None:
"""Connecte le device, applique la configuration transpondeur continu."""
self._device.connect()
# 1. Filtre d'adresses : seules les requêtes pour my_address déclenchent une
# réponse. Les 7 autres slots sont 0xFF (désactivé).
addresses = [self._my_address] + [0xFF] * 7
self._device.set_usbl_request_address_filter(addresses[:8])
# 2. Filtre d'écho actif (évite de répondre à son propre écho réverbéré).
self._device.set_usbl_monitor_config(
enable=True,
echo_filter_response_us=self._echo_filter_us,
echo_filter_request_us=self._echo_filter_us,
)
# 3. Sync slot TDMA optionnel (utile en multi-slave pour éviter collisions).
if self._sync is not None:
self._device.set_sync_mode(
slot_total=self._sync.slot_total,
slot_index=self._sync.slot_index,
slot_duration=self._sync.slot_duration,
enable_delay=False, # False côté slave (le master ordonne)
)
# 4. Active la fenêtre de réponse permanente (timeout = 0xFFFFFFFF µs).
self._device.set_usbl_transponder(enable=True)
# 5. Branche les callbacks Python sur les frames asynchrones.
self._device.register_callback(ID_USBL_SOLUTION, self._handle_usbl_solution)
self._device.register_callback(ID_DIST, self._handle_distance)
# 6. Watchdog optionnel.
if self._watchdog_timeout_s > 0:
self._watchdog_thread = threading.Thread(
target=self._watchdog_loop, daemon=True, name="kogger-watchdog"
)
self._watchdog_thread.start()
def stop(self) -> None:
"""Désactive le transpondeur, déconnecte proprement."""
self._stop_event.set()
try:
self._device.set_usbl_transponder(enable=False)
except Exception:
pass # le device peut déjà être déconnecté
self._device.unregister_callback(ID_USBL_SOLUTION)
self._device.unregister_callback(ID_DIST)
self._device.disconnect()
def run_forever(self, tick_s: float = 0.5) -> None:
"""Bloque le main thread jusqu'à `stop()` ou KeyboardInterrupt."""
try:
while not self._stop_event.is_set():
time.sleep(tick_s)
except KeyboardInterrupt:
pass
# ------------------------------------------------------------------ internals
def _handle_usbl_solution(self, message: dict) -> None:
self.state.last_ping_at = time.time()
self.state.pings_received += 1
self.state.last_ping_id = message.get("id")
self.state.last_snr = message.get("snr")
# Distance hardware-computed côté antenne, exposée dans l'USBL solution.
for k in ("distance_m", "slant_range_m", "distance"):
if k in message:
self.state.last_distance_m = message[k]
break
if self._on_ping:
try:
self._on_ping(message)
except Exception as e:
# On n'interrompt jamais le reader thread du driver pour une
# exception applicative.
print(f"[ContinuousTransponder] on_ping callback error: {e}")
def _handle_distance(self, message: dict) -> None:
if self._on_distance:
try:
self._on_distance(message)
except Exception as e:
print(f"[ContinuousTransponder] on_distance callback error: {e}")
def _watchdog_loop(self) -> None:
"""Si on n'a rien reçu depuis `watchdog_timeout_s`, ré-applique la config."""
while not self._stop_event.wait(self._watchdog_timeout_s / 2):
silent_for = time.time() - self.state.last_ping_at
if (
self.state.last_ping_at > 0
and silent_for > self._watchdog_timeout_s
):
print(
f"[ContinuousTransponder] watchdog: silent {silent_for:.1f}s, "
f"re-applying config"
)
try:
self._device.set_usbl_transponder(enable=True)
except Exception as e:
print(f"[ContinuousTransponder] watchdog re-arm failed: {e}")
# ----------------------------------------------------------------------- CLI
def _main() -> int:
p = argparse.ArgumentParser(description="Kogger USBL — transpondeur continu")
p.add_argument("--port", required=True, help="Port série (ex. /dev/ttyUSB0)")
p.add_argument("--address", type=int, required=True, help="Mon ID Kogger (1..7)")
p.add_argument("--baudrate", type=int, default=921600)
p.add_argument("--vehicle", default=None, help="Étiquette véhicule (logs CSV)")
p.add_argument("--echo-filter-us", type=int, default=400_000)
p.add_argument("--watchdog-s", type=float, default=0.0,
help="Re-arm si silence > X secondes (0 = off)")
p.add_argument("--slot-total", type=int, default=0)
p.add_argument("--slot-index", type=int, default=0)
p.add_argument("--slot-duration", type=float, default=0.0)
p.add_argument("--log-level", default="INFO")
args = p.parse_args()
sync = None
if args.slot_total > 0 and args.slot_duration > 0:
sync = SyncSlot(args.slot_total, args.slot_index, args.slot_duration)
t = ContinuousTransponder(
port=args.port,
my_address=args.address,
baudrate=args.baudrate,
vehicle_name=args.vehicle,
echo_filter_us=args.echo_filter_us,
sync=sync,
watchdog_timeout_s=args.watchdog_s,
log_level=args.log_level,
)
def on_ping(msg):
d = t.state.last_distance_m
d_str = f"{d:.2f} m" if d is not None else ""
print(
f"ping #{t.state.pings_received} from id={msg.get('id')} "
f"snr={msg.get('snr')} dist={d_str}"
)
t.on_ping_received(on_ping)
print(f"Starting transponder address={args.address} on {args.port} (Ctrl-C pour arrêter)")
t.start()
try:
t.run_forever()
finally:
t.stop()
print(f"Stopped. Total pings received: {t.state.pings_received}")
return 0
if __name__ == "__main__":
sys.exit(_main())