User's Manual
Python Library for PCIe Gen6 HYDRA JBOF Systems
Version 1.0.0 | November 2025

Table of Contents

1. Introduction

The Serial Cables HYDRA Controller is a comprehensive Python library designed for controlling and monitoring Serial Cables PCIe Gen6 HYDRA 8-Bay Passive JBOF (Just a Bunch of Flash) enclosures. This library provides complete hardware control, environmental monitoring, and alerting capabilities through a serial CLI interface.

Key Features

Hardware Compatibility

ParameterSpecification
ModelSerial Cables PCIe Gen6 8-Bay Passive JBOF
Firmware Version0.0.2 and above
Connection InterfaceUSB Type-C serial interface
Serial Configuration115200 baud, 8N1
Operating SystemsWindows, Linux, macOS
Python Version3.7 and above

2. Installation

System Requirements

Installation Methods

From PyPI (Recommended)

Install the latest stable version from the Python Package Index:

pip install serialcables-hydra

Verification

Verify your installation by importing the library:

python -c "from serialcables_hydra import JBOFController; print('Installation successful')"
Success: If the import completes without errors, your installation is ready to use.

3. Quick Start Guide

Basic Connection and Monitoring

This example demonstrates the essential operations for connecting to and monitoring your HYDRA JBOF:

from serialcables_hydra import JBOFController, PowerState # Initialize controller (adjust port for your system) controller = JBOFController(port='COM3') # Windows # controller = JBOFController(port='/dev/ttyUSB0') # Linux # Connect to HYDRA system if controller.connect(): print("Connected to HYDRA JBOF successfully!") # Get system information sys_info = controller.get_system_info() print(f"Model: {sys_info.model}") print(f"Firmware: {sys_info.firmware_version}") print(f"Serial Number: {sys_info.serial_number}") # Check slot status slots = controller.show_slot_info() print("\nSlot Status:") for slot in slots: status = "SSD Present" if slot.present else "Empty" print(f"Slot {slot.slot_number}: {status}") # Get environmental data env_data = controller.get_environmental_data() print(f"\nEnvironmental Status:") print(f"PSU Voltage: {env_data['voltages']['psu_12v']:.2f}V") print(f"MCU Temperature: {env_data['temperatures']['mcu']:.1f}°C") print(f"Fan 1 Speed: {env_data['fan_speeds']['fan_1']} RPM") # Disconnect when done controller.disconnect() else: print("Failed to connect to HYDRA JBOF")

Essential SSD Management

Control power and monitor individual SSD slots:

from serialcables_hydra import JBOFController, PowerState import time controller = JBOFController(port='COM3') controller.connect() # Check current power status power_status = controller.get_slot_power_status() print("Current slot power status:") for slot_num, status in power_status.items(): print(f"Slot {slot_num}: {status}") # Power cycle slot 1 (if SSD is present) print("\nPower cycling slot 1...") controller.slot_power(1, PowerState.OFF) time.sleep(2) # Wait for clean shutdown controller.slot_power(1, PowerState.ON) # Control LED for visual indication controller.control_host_led(1, PowerState.ON) # Turn on LED time.sleep(3) controller.control_host_led(1, PowerState.OFF) # Turn off LED controller.disconnect()
Important: Always ensure SSDs are properly shut down before powering off slots to prevent data corruption. The library provides safe power cycling with appropriate delays.

4. Hardware Setup

Physical Connection

  1. Power Connection: Ensure the HYDRA JBOF is properly connected to power and powered on
  2. USB Connection: Connect the USB Type-C cable between your computer and the JBOF's management port
  3. SSD Installation: Install NVMe SSDs in the desired slots (1-8)
  4. PCIe Connection: Connect PCIe cables from the host system to the JBOF

Serial Port Identification

Windows

Linux

# List available serial ports ls /dev/tty* # Check for USB serial devices ls /dev/ttyUSB* /dev/ttyACM* # View detailed information dmesg | grep tty

macOS

# List serial ports ls /dev/tty.* # Look for USB serial devices ls /dev/tty.usbserial-* /dev/tty.usbmodem-*

Permissions Setup (Linux/macOS)

Grant access to serial ports:

# Temporary permission sudo chmod 666 /dev/ttyUSB0 # Permanent solution - add user to dialout group sudo usermod -a -G dialout $USER # Log out and back in for changes to take effect
Note: The exact port name may vary depending on your system configuration and connected devices. Always verify the correct port before connecting.

5. API Reference

Core Classes

JBOFController / HydraController

Main controller class for HYDRA JBOF interaction. Both class names are equivalent and can be used interchangeably.

Constructor

JBOFController(port: str, baudrate: int = 115200, timeout: float = 1.0)
ParameterTypeDefaultDescription
portstrRequiredSerial port path (e.g., 'COM3', '/dev/ttyUSB0')
baudrateint115200Serial communication baud rate
timeoutfloat1.0Command timeout in seconds

System Control Methods

connect() → bool

Establish serial connection to the JBOF system.

controller = JBOFController('COM3') if controller.connect(): print("Connection successful")

disconnect()

Close the serial connection and clean up resources.

controller.disconnect()

system_power(state: PowerState) → bool

Control main system power state.

# Power on the system controller.system_power(PowerState.ON) # Power off the system controller.system_power(PowerState.OFF)

reset() → bool

Perform a soft reset of the MCU.

controller.reset()

Slot Management Methods

slot_power(slot: Union[int, str], state: PowerState) → bool

Control power for specific slot(s).

# Power on slot 1 controller.slot_power(1, PowerState.ON) # Power off slot 3 controller.slot_power(3, PowerState.OFF) # Power on all slots controller.slot_power('all', PowerState.ON)

get_slot_power_status() → Dict[int, str]

Retrieve current power status for all slots.

status = controller.get_slot_power_status() for slot_num, power_state in status.items(): print(f"Slot {slot_num}: {power_state}")

show_slot_info() → List[SlotInfo]

Get detailed information about all slots.

slots = controller.show_slot_info() for slot in slots: print(f"Slot {slot.slot_number}:") print(f" Present: {slot.present}") print(f" Paddle Card: {slot.paddle_card}") print(f" Temperature: {slot.temperature}°C")

Environmental Monitoring Methods

get_environmental_data() → Dict

Retrieve comprehensive environmental data.

env_data = controller.get_environmental_data() # Access temperatures for location, temp in env_data['temperatures'].items(): print(f"{location}: {temp:.1f}°C") # Access voltages for rail, voltage in env_data['voltages'].items(): print(f"{rail}: {voltage:.2f}V") # Access fan speeds for fan, rpm in env_data['fan_speeds'].items(): print(f"{fan}: {rpm} RPM")

get_system_info() → SystemInfo

Get complete system information.

sys_info = controller.get_system_info() print(f"Company: {sys_info.company}") print(f"Model: {sys_info.model}") print(f"Serial Number: {sys_info.serial_number}") print(f"Firmware: {sys_info.firmware_version}")

LED Control Methods

control_host_led(slot: Union[int, str], state: PowerState) → bool

Control host LED on EDSFF drives.

# Turn on host LED for slot 1 controller.control_host_led(1, PowerState.ON) # Turn off host LED for all slots controller.control_host_led('all', PowerState.OFF)

control_fault_led(slot: Union[int, str], state: PowerState) → bool

Control fault LED indicators.

# Signal fault condition on slot 2 controller.control_fault_led(2, PowerState.ON)

Fan Control Methods

set_fan_speed(fan_id: int, duty_cycle: int) → bool

Set fan PWM duty cycle for speed control.

# Set fan 1 to 75% speed controller.set_fan_speed(1, 75) # Set fan 2 to maximum speed controller.set_fan_speed(2, 100) # Set fan 1 to minimum speed controller.set_fan_speed(1, 30)
Caution: Setting fan speed too low may result in overheating. Monitor temperatures when adjusting fan speeds.

Advanced Features

I2C/SMBus Communication

i2c_read(address: int, slot: int, register: int, length: int) → List[int]

Read data from I2C/SMBus devices connected to SSD slots.

# Read 8 bytes from device 0x50, register 0x00 on slot 1 data = controller.i2c_read(0x50, 1, 0x00, 8) if data: hex_data = ' '.join(f'{b:02X}' for b in data) print(f"Data read: {hex_data}")

i2c_write(address: int, slot: int, data: List[int]) → bool

Write data to I2C/SMBus devices.

# Write data to device 0x50 on slot 1 data = [0x00, 0x01, 0x02, 0x03] success = controller.i2c_write(0x50, 1, data)

Control Buzzer

from serialcables_hydra import BuzzerState # Turn buzzer on controller.control_buzzer(BuzzerState.ON) # Turn buzzer off controller.control_buzzer(BuzzerState.OFF) # Enable buzzer for alerts controller.control_buzzer(BuzzerState.ENABLE)

Additional Reset Functions

smbus_reset(slot: Union[int, str]) → bool

Send SMBus reset signal to selected slot(s).

controller.smbus_reset(1) # Reset SMBus for slot 1 controller.smbus_reset('all') # Reset SMBus for all slots

ssd_reset(slot: Union[int, str], channel: Optional[str] = None) → bool

Send PERST# reset signal to selected slot(s).

controller.ssd_reset(1) # Reset both channels for slot 1 controller.ssd_reset(2, 'a') # Reset only channel A for slot 2 controller.ssd_reset(3, 'b') # Reset only channel B for slot 3

6. Monitoring and Alerting

Real-time Monitoring

The HYDRA controller provides comprehensive monitoring capabilities for proactive system management.

Continuous Monitoring Loop

from serialcables_hydra import JBOFController, BuzzerState import time def continuous_monitor(port, duration=300): controller = JBOFController(port) controller.connect() start_time = time.time() alert_count = 0 print("Starting continuous monitoring...") print("Press Ctrl+C to stop") try: while time.time() - start_time < duration: env_data = controller.get_environmental_data() # Monitor temperatures for location, temp in env_data['temperatures'].items(): if temp > 55: # Critical temperature print(f"CRITICAL: High temperature {location}: {temp:.1f}°C") controller.control_buzzer(BuzzerState.ON) alert_count += 1 elif temp > 45: # Warning temperature print(f"WARNING: Elevated temperature {location}: {temp:.1f}°C") # Monitor voltages psu_voltage = env_data['voltages']['psu_12v'] if psu_voltage < 11.5 or psu_voltage > 12.5: print(f"WARNING: PSU voltage out of range: {psu_voltage:.2f}V") alert_count += 1 # Monitor fan speeds for fan, rpm in env_data['fan_speeds'].items(): if rpm < 3000: print(f"ALERT: Low fan speed {fan}: {rpm} RPM") controller.control_buzzer(BuzzerState.ON) alert_count += 1 # Display current status every 30 seconds if int(time.time() - start_time) % 30 == 0: print(f"Status: {alert_count} alerts, PSU: {psu_voltage:.2f}V") time.sleep(5) # Check every 5 seconds except KeyboardInterrupt: print("\nMonitoring stopped by user") finally: controller.control_buzzer(BuzzerState.OFF) controller.disconnect() print(f"Monitoring complete. Total alerts: {alert_count}") # Run monitoring for 5 minutes continuous_monitor('COM3', duration=300)

Alert Thresholds

ParameterWarning LevelCritical Level
Temperature45°C55°C
PSU Voltage< 11.5V or > 12.5V< 11.0V or > 13.0V
Fan Speed< 3000 RPM< 1000 RPM
Current> 80% rated> 95% rated

Data Logging

Implement data logging for historical analysis and trending:

import csv import datetime from serialcables_hydra import JBOFController def log_environmental_data(port, log_file, interval=60, duration=3600): controller = JBOFController(port) controller.connect() # Create CSV file with headers with open(log_file, 'w', newline='') as csvfile: fieldnames = ['timestamp', 'mcu_temp', 'psu_voltage', 'fan1_rpm', 'fan2_rpm', 'slot1_temp', 'slot1_power'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() start_time = time.time() while time.time() - start_time < duration: env_data = controller.get_environmental_data() slots = controller.show_slot_info() # Log current data log_entry = { 'timestamp': datetime.datetime.now().isoformat(), 'mcu_temp': env_data['temperatures']['mcu'], 'psu_voltage': env_data['voltages']['psu_12v'], 'fan1_rpm': env_data['fan_speeds']['fan_1'], 'fan2_rpm': env_data['fan_speeds']['fan_2'], 'slot1_temp': slots[0].temperature if slots else 0, 'slot1_power': slots[0].power if slots else 0 } writer.writerow(log_entry) csvfile.flush() # Ensure data is written print(f"Logged data at {log_entry['timestamp']}") time.sleep(interval) controller.disconnect() print(f"Data logging complete. File saved: {log_file}") # Log data every minute for 1 hour log_environmental_data('COM3', 'hydra_log.csv', interval=60, duration=3600)

7. Troubleshooting

Connection Issues

Problem: Cannot Connect to Serial Port

# Test port availability import serial try: ser = serial.Serial('COM3', 115200, timeout=1) print("Port is available") ser.close() except serial.SerialException as e: print(f"Port error: {e}")

Solutions:

Problem: Commands Timeout

Solutions:

Problem: Inconsistent Responses

Solutions:

Hardware Issues

Problem: SSD Not Detected

Diagnostic Steps:

# Check slot status slots = controller.show_slot_info() for slot in slots: print(f"Slot {slot.slot_number}: Present={slot.present}, Power={slot.power_status}") # Verify power status power_status = controller.get_slot_power_status() print("Power status:", power_status) # Check clock signals clock_status = controller.check_clock_input() print("Clock status:", clock_status)

Solutions:

Problem: High Temperature Alerts

Diagnostic Steps:

# Check all temperature sensors env_data = controller.get_environmental_data() for location, temp in env_data['temperatures'].items(): status = "CRITICAL" if temp > 55 else "WARNING" if temp > 45 else "OK" print(f"{location}: {temp:.1f}°C [{status}]") # Check fan operation for fan, rpm in env_data['fan_speeds'].items(): status = "LOW" if rpm < 3000 else "OK" print(f"{fan}: {rpm} RPM [{status}]")

Solutions:

Software Issues

Problem: Import Errors

# Verify installation pip show serialcables-hydra # Check Python path import sys print("Python path:", sys.path) # Test basic import try: from serialcables_hydra import JBOFController print("Import successful") except ImportError as e: print(f"Import failed: {e}")

Problem: Permission Denied (Linux/macOS)

# Check current user groups groups # Add user to dialout group sudo usermod -a -G dialout $USER # Alternative: temporary permission sudo chmod 666 /dev/ttyUSB0

Diagnostic Tools

System Health Check

def system_health_check(port): """Comprehensive system health check""" try: controller = JBOFController(port) if not controller.connect(): print("[FAILED] Connection failed") return False print("[SUCCESS] Connection successful") # Run built-in diagnostics diag_results = controller.run_diagnostics() print("\nDiagnostic Results:") for device, status in diag_results.items(): symbol = "[OK]" if status == "OK" else "[FAIL]" print(f"{symbol} {device}: {status}") # Check environmental status env_data = controller.get_environmental_data() print("\nEnvironmental Status:") # Temperature check temps_ok = all(temp < 50 for temp in env_data['temperatures'].values()) print(f"[{'OK' if temps_ok else 'WARN'}] Temperatures: {'OK' if temps_ok else 'Elevated'}") # Fan check fans_ok = all(rpm > 3000 for rpm in env_data['fan_speeds'].values()) print(f"[{'OK' if fans_ok else 'FAIL'}] Fans: {'OK' if fans_ok else 'Low Speed'}") # Voltage check voltage = env_data['voltages']['psu_12v'] voltage_ok = 11.5 <= voltage <= 12.5 print(f"[{'OK' if voltage_ok else 'WARN'}] PSU Voltage: {voltage:.2f}V {'OK' if voltage_ok else 'Out of Range'}") controller.disconnect() return True except Exception as e: print(f"[FAILED] Health check failed: {e}") return False # Run health check system_health_check('COM3')

8. Examples

Complete System Management

This example demonstrates comprehensive system management including monitoring, alerts, and automated responses:

from serialcables_hydra import JBOFController, PowerState, BuzzerState import time import logging # Configure logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) class HydraSystemManager: def __init__(self, port, temp_warning=45, temp_critical=55): self.controller = JBOFController(port) self.temp_warning = temp_warning self.temp_critical = temp_critical self.alert_count = 0 def connect(self): """Establish connection and perform initial checks""" if not self.controller.connect(): logger.error("Failed to connect to JBOF") return False logger.info("Connected to JBOF successfully") # Initial system check sys_info = self.controller.get_system_info() logger.info(f"System: {sys_info.model} (FW: {sys_info.firmware_version})") return True def monitor_system(self, duration=3600): """Monitor system for specified duration""" start_time = time.time() last_alert_time = 0 logger.info(f"Starting system monitoring for {duration} seconds") try: while time.time() - start_time < duration: env_data = self.controller.get_environmental_data() current_time = time.time() # Temperature monitoring max_temp = max(env_data['temperatures'].values()) if max_temp > self.temp_critical: self.handle_critical_temperature(max_temp) elif max_temp > self.temp_warning: self.handle_temperature_warning(max_temp) # Fan monitoring min_fan_speed = min(env_data['fan_speeds'].values()) if min_fan_speed < 1000: self.handle_fan_failure(min_fan_speed) elif min_fan_speed < 3000: self.handle_fan_warning(min_fan_speed) # Voltage monitoring voltage = env_data['voltages']['psu_12v'] if not (11.5 <= voltage <= 12.5): self.handle_voltage_warning(voltage) # Log status every 5 minutes if current_time - last_alert_time > 300: logger.info(f"Status: Temp={max_temp:.1f}°C, Voltage={voltage:.2f}V, " f"Fans={min_fan_speed}RPM, Alerts={self.alert_count}") last_alert_time = current_time time.sleep(30) # Check every 30 seconds except KeyboardInterrupt: logger.info("Monitoring stopped by user") finally: self.controller.control_buzzer(BuzzerState.OFF) logger.info(f"Monitoring complete. Total alerts: {self.alert_count}") def handle_critical_temperature(self, temp): """Handle critical temperature condition""" logger.critical(f"CRITICAL TEMPERATURE: {temp:.1f}°C") self.controller.control_buzzer(BuzzerState.ON) self.alert_count += 1 # Increase fan speeds to maximum self.controller.set_fan_speed(1, 100) self.controller.set_fan_speed(2, 100) logger.info("Fan speeds increased to maximum") def handle_temperature_warning(self, temp): """Handle temperature warning""" logger.warning(f"Temperature warning: {temp:.1f}°C") self.alert_count += 1 def handle_fan_failure(self, rpm): """Handle fan failure""" logger.critical(f"FAN FAILURE: {rpm} RPM") self.controller.control_buzzer(BuzzerState.ON) self.alert_count += 1 def handle_fan_warning(self, rpm): """Handle fan speed warning""" logger.warning(f"Low fan speed: {rpm} RPM") self.alert_count += 1 def handle_voltage_warning(self, voltage): """Handle voltage out of range""" logger.warning(f"Voltage out of range: {voltage:.2f}V") self.alert_count += 1 def power_cycle_slot(self, slot_number): """Safely power cycle a specific slot""" logger.info(f"Power cycling slot {slot_number}") # Turn on indicator LED self.controller.control_host_led(slot_number, PowerState.ON) # Power off self.controller.slot_power(slot_number, PowerState.OFF) logger.info(f"Slot {slot_number} powered off") time.sleep(5) # Wait for clean shutdown # Power on self.controller.slot_power(slot_number, PowerState.ON) logger.info(f"Slot {slot_number} powered on") time.sleep(3) # Turn off indicator LED self.controller.control_host_led(slot_number, PowerState.OFF) def disconnect(self): """Clean disconnection""" if self.controller: self.controller.disconnect() logger.info("Disconnected from JBOF") # Usage example if __name__ == "__main__": manager = HydraSystemManager('COM3', temp_warning=45, temp_critical=55) if manager.connect(): try: # Monitor system for 1 hour manager.monitor_system(duration=3600) finally: manager.disconnect()

Automated Slot Testing

Automated testing routine for all populated slots:

def automated_slot_test(port): """Comprehensive automated slot testing""" controller = JBOFController(port) if not controller.connect(): print("Connection failed") return print("Starting automated slot testing...") # Get initial slot status slots = controller.show_slot_info() populated_slots = [slot for slot in slots if slot.present] if not populated_slots: print("No SSDs detected for testing") controller.disconnect() return print(f"Testing {len(populated_slots)} populated slots") test_results = [] for slot in populated_slots: slot_num = slot.slot_number print(f"\nTesting Slot {slot_num}...") test_result = { 'slot': slot_num, 'initial_temp': slot.temperature, 'power_cycle_success': False, 'led_test_success': False, 'final_temp': None } try: # Test LED control print(" Testing LED control...") controller.control_host_led(slot_num, PowerState.ON) time.sleep(2) controller.control_host_led(slot_num, PowerState.OFF) test_result['led_test_success'] = True print(" [SUCCESS] LED test passed") # Test power cycling print(" Testing power cycle...") initial_power = controller.get_slot_power_status()[slot_num] # Power off controller.slot_power(slot_num, PowerState.OFF) time.sleep(3) off_power = controller.get_slot_power_status()[slot_num] # Power on controller.slot_power(slot_num, PowerState.ON) time.sleep(5) final_power = controller.get_slot_power_status()[slot_num] if initial_power == 'on' and off_power == 'off' and final_power == 'on': test_result['power_cycle_success'] = True print(" [SUCCESS] Power cycle test passed") else: print(f" [FAILED] Power cycle test failed: {initial_power}→{off_power}→{final_power}") # Get final temperature updated_slots = controller.show_slot_info() final_slot = next(s for s in updated_slots if s.slot_number == slot_num) test_result['final_temp'] = final_slot.temperature except Exception as e: print(f" ❌ Test failed: {e}") test_results.append(test_result) time.sleep(2) # Brief pause between slot tests # Print summary print("\n" + "="*50) print("TEST SUMMARY") print("="*50) for result in test_results: slot_num = result['slot'] led_status = "PASS" if result['led_test_success'] else "FAIL" power_status = "PASS" if result['power_cycle_success'] else "FAIL" temp_change = result['final_temp'] - result['initial_temp'] if result['final_temp'] else 0 print(f"Slot {slot_num}:") print(f" LED Test: {led_status}") print(f" Power Test: {power_status}") print(f" Temperature: {result['initial_temp']:.1f}°C → {result['final_temp']:.1f}°C ({temp_change:+.1f}°C)") print() # Overall results total_tests = len(test_results) led_passes = sum(1 for r in test_results if r['led_test_success']) power_passes = sum(1 for r in test_results if r['power_cycle_success']) print(f"Overall Results:") print(f" LED Tests: {led_passes}/{total_tests} passed") print(f" Power Tests: {power_passes}/{total_tests} passed") controller.disconnect() return test_results # Run automated testing results = automated_slot_test('COM3')

9. Command Line Tools

The HYDRA Controller package includes command-line tools for system monitoring and control.

hydra-monitor

Continuous monitoring tool with real-time display and alerting.

Basic Usage

# Basic monitoring hydra-monitor --port COM3 # Monitor with custom settings hydra-monitor --port /dev/ttyUSB0 --interval 30 --duration 3600 # Monitor with logging hydra-monitor --port COM3 --log hydra_data.csv --interval 60 # Monitor with custom alert thresholds hydra-monitor --port COM3 --temp-warning 50 --temp-critical 60 --fan-min 4000

Command Options

OptionDescriptionDefault
--portSerial port pathRequired
--intervalMonitoring interval (seconds)30
--durationTotal duration (seconds, 0=infinite)0
--logCSV log file pathNone
--temp-warningTemperature warning threshold (°C)45
--temp-criticalTemperature critical threshold (°C)55
--fan-minMinimum fan speed (RPM)3000
--voltage-minMinimum voltage (V)11.5
--voltage-maxMaximum voltage (V)12.5

hydra-cli

Command-line interface for direct system control and status queries.

Available Commands

# System status hydra-cli --port COM3 status # Power control hydra-cli --port COM3 power-on --slot 1 hydra-cli --port COM3 power-off --slot 2 hydra-cli --port COM3 power-cycle --slot 3 # Environmental data hydra-cli --port COM3 environment hydra-cli --port COM3 temperatures hydra-cli --port COM3 fans # LED control hydra-cli --port COM3 led-on --slot 1 hydra-cli --port COM3 led-off --slot all # Diagnostics hydra-cli --port COM3 diagnostics hydra-cli --port COM3 version

Output Formats

# Default human-readable output hydra-cli --port COM3 status # JSON output for scripting hydra-cli --port COM3 status --format json # CSV output for data analysis hydra-cli --port COM3 environment --format csv

Integration with Scripts

Example shell script for automated monitoring:

#!/bin/bash # HYDRA monitoring script PORT="/dev/ttyUSB0" LOG_DIR="/var/log/hydra" DATE=$(date +%Y%m%d_%H%M%S) # Create log directory mkdir -p $LOG_DIR # Start background monitoring hydra-monitor --port $PORT --log "$LOG_DIR/hydra_$DATE.csv" --duration 86400 & MONITOR_PID=$! echo "HYDRA monitoring started (PID: $MONITOR_PID)" echo "Log file: $LOG_DIR/hydra_$DATE.csv" # Function to check system status check_status() { hydra-cli --port $PORT status --format json > "$LOG_DIR/status_$DATE.json" # Check for critical conditions CRITICAL=$(hydra-cli --port $PORT temperatures | grep -c "CRITICAL") if [ $CRITICAL -gt 0 ]; then echo "CRITICAL: High temperature detected!" # Send alert (email, SMS, etc.) # mail -s "HYDRA Critical Alert" admin@company.com < "$LOG_DIR/status_$DATE.json" fi } # Check status every 5 minutes while kill -0 $MONITOR_PID 2>/dev/null; do check_status sleep 300 done echo "Monitoring completed"

10. Support

Getting Help

For technical support and assistance with the Serial Cables HYDRA Controller:

Contact Information

Before Contacting Support

Please gather the following information to help expedite support:

System Information

from serialcables_hydra import JBOFController # Collect system information for support def collect_support_info(port): info = { 'library_version': '1.0.0', 'python_version': None, 'platform': None, 'jbof_info': None, 'connection_status': False } # Python and platform info import sys, platform info['python_version'] = sys.version info['platform'] = platform.platform() try: controller = JBOFController(port) if controller.connect(): info['connection_status'] = True sys_info = controller.get_system_info() info['jbof_info'] = { 'model': sys_info.model, 'firmware': sys_info.firmware_version, 'serial': sys_info.serial_number } controller.disconnect() except Exception as e: info['connection_error'] = str(e) return info # Generate support information support_data = collect_support_info('COM3') print("Support Information:") for key, value in support_data.items(): print(f"{key}: {value}")

Information to Include

Common Support Scenarios

Hardware Compatibility

Verify your hardware is compatible:

Performance Issues

For performance-related concerns:

Integration Support

For help integrating with your systems:

Community Resources

Feedback and Contributions

We welcome feedback and contributions to improve the HYDRA Controller library: