Enhance disk usage retrieval with multiple fallbacks for Windows compatibility
- Implemented a new method `_get_disk_usage_safe` in `PLCDataStreamer` to safely retrieve disk usage information using `psutil` and `shutil` with fallbacks for different scenarios. - Updated the disk usage calculation logic to handle potential errors and log warnings when disk usage retrieval fails. - Modified the `system_state.json` to reorder active datasets and add a new `plotjuggler_path` entry. - Added a comprehensive test script `test_disk_space.py` to validate the disk space calculation functionality via the API.
This commit is contained in:
parent
6302acfc0f
commit
aa75a46d84
File diff suppressed because it is too large
Load Diff
|
@ -598,7 +598,12 @@ class PLCDataStreamer:
|
|||
os.makedirs(records_path)
|
||||
|
||||
# Get disk usage for the drive where records are stored
|
||||
usage = psutil.disk_usage(os.path.abspath(records_path))
|
||||
# Use multiple fallback methods for Windows compatibility
|
||||
usage = self._get_disk_usage_safe(records_path)
|
||||
if usage is None:
|
||||
if hasattr(self, "logger"):
|
||||
self.logger.warning("Could not get disk usage information")
|
||||
return None
|
||||
|
||||
# Calculate average CSV file size (estimate based on active datasets)
|
||||
avg_file_size_per_hour = self._estimate_csv_size_per_hour()
|
||||
|
@ -633,6 +638,63 @@ class PLCDataStreamer:
|
|||
self.logger.error(f"Error calculating disk space: {e}")
|
||||
return None
|
||||
|
||||
def _get_disk_usage_safe(self, path):
|
||||
"""Safely get disk usage with Windows compatibility fallbacks"""
|
||||
import shutil
|
||||
from collections import namedtuple
|
||||
|
||||
DiskUsage = namedtuple("DiskUsage", ["total", "used", "free", "percent"])
|
||||
|
||||
try:
|
||||
# Method 1: Try psutil with absolute path
|
||||
abs_path = os.path.abspath(path)
|
||||
usage = psutil.disk_usage(abs_path)
|
||||
return DiskUsage(
|
||||
total=usage.total,
|
||||
used=usage.used,
|
||||
free=usage.free,
|
||||
percent=round((usage.used / usage.total) * 100, 1),
|
||||
)
|
||||
except (SystemError, OSError, Exception) as e:
|
||||
if hasattr(self, "logger"):
|
||||
self.logger.warning(f"psutil.disk_usage failed for {path}: {e}")
|
||||
|
||||
try:
|
||||
# Method 2: Try psutil with drive root
|
||||
drive = os.path.splitdrive(os.path.abspath(path))[0]
|
||||
if drive:
|
||||
drive_root = drive + os.sep # e.g., "D:\"
|
||||
if hasattr(self, "logger"):
|
||||
self.logger.info(f"Trying psutil with drive root: {drive_root}")
|
||||
usage = psutil.disk_usage(drive_root)
|
||||
return DiskUsage(
|
||||
total=usage.total,
|
||||
used=usage.used,
|
||||
free=usage.free,
|
||||
percent=round((usage.used / usage.total) * 100, 1),
|
||||
)
|
||||
except Exception as e2:
|
||||
if hasattr(self, "logger"):
|
||||
self.logger.warning(
|
||||
f"psutil.disk_usage with drive root failed: {e2}"
|
||||
)
|
||||
|
||||
try:
|
||||
# Method 3: Use shutil.disk_usage (Python 3.3+)
|
||||
if hasattr(self, "logger"):
|
||||
self.logger.info("Trying shutil.disk_usage as fallback")
|
||||
total, used, free = shutil.disk_usage(path)
|
||||
return DiskUsage(
|
||||
total=total,
|
||||
used=used,
|
||||
free=free,
|
||||
percent=round((used / total) * 100, 1),
|
||||
)
|
||||
except Exception as e3:
|
||||
if hasattr(self, "logger"):
|
||||
self.logger.error(f"All disk usage methods failed: {e3}")
|
||||
return None
|
||||
|
||||
def _estimate_csv_size_per_hour(self) -> float:
|
||||
"""Estimate CSV file size per hour based on active datasets and variables"""
|
||||
try:
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
"should_stream": false,
|
||||
"active_datasets": [
|
||||
"Fast",
|
||||
"Test",
|
||||
"DAR"
|
||||
"DAR",
|
||||
"Test"
|
||||
]
|
||||
},
|
||||
"auto_recovery_enabled": true,
|
||||
"last_update": "2025-08-22T15:01:09.609437"
|
||||
"last_update": "2025-08-22T16:03:42.919215",
|
||||
"plotjuggler_path": "C:\\Program Files\\PlotJuggler\\plotjuggler.exe"
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to validate the disk space calculation fix
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
|
||||
|
||||
def test_disk_space_api():
|
||||
"""Test the /api/status endpoint to see if disk_space_info works"""
|
||||
|
||||
url = "http://localhost:5050/api/status"
|
||||
|
||||
try:
|
||||
print("🔍 Testing disk space calculation...")
|
||||
|
||||
# Make the API request
|
||||
response = requests.get(url, timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
|
||||
# Check if disk_space_info exists and is valid
|
||||
disk_info = data.get("disk_space_info")
|
||||
|
||||
if disk_info is not None:
|
||||
print("✅ Disk space information retrieved successfully!")
|
||||
print(f"📁 Free space: {disk_info.get('free_space', 'N/A')}")
|
||||
print(f"📊 Total space: {disk_info.get('total_space', 'N/A')}")
|
||||
print(f"💾 Used space: {disk_info.get('used_space', 'N/A')}")
|
||||
print(f"📈 Percent used: {disk_info.get('percent_used', 'N/A')}%")
|
||||
print(
|
||||
f"⏱️ Recording time left: {disk_info.get('recording_time_left', 'N/A')}"
|
||||
)
|
||||
print(
|
||||
f"📝 Avg file size per hour: {disk_info.get('avg_file_size_per_hour', 'N/A')}"
|
||||
)
|
||||
|
||||
return True
|
||||
else:
|
||||
print("❌ disk_space_info is null - error occurred during calculation")
|
||||
return False
|
||||
|
||||
else:
|
||||
print(f"❌ HTTP Error: {response.status_code}")
|
||||
print(response.text)
|
||||
return False
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"❌ Request failed: {e}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"❌ Unexpected error: {e}")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 Testing disk space calculation fix...")
|
||||
print("=" * 50)
|
||||
|
||||
# Wait a bit for server to be ready
|
||||
time.sleep(2)
|
||||
|
||||
success = test_disk_space_api()
|
||||
|
||||
print("=" * 50)
|
||||
if success:
|
||||
print("✅ Test PASSED - Disk space calculation is working!")
|
||||
else:
|
||||
print("❌ Test FAILED - Disk space calculation has issues")
|
Loading…
Reference in New Issue