#! /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="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {name}:{function}:{line} - {message}")
# --- 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(' 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.")