debug scripts
Some checks failed
Python CI / test (3.12) (push) Failing after 18m41s
Python CI / test (3.13) (push) Failing after 19m45s

This commit is contained in:
Duncan Tourolle 2025-11-23 15:16:25 +01:00
parent 73102392dd
commit c62b8eff38
5 changed files with 593 additions and 1 deletions

201
examples/test_hardware_display.py Executable file
View File

@ -0,0 +1,201 @@
#!/usr/bin/env python3
"""
Simple test to verify the hardware HAL can display images.
Creates a test pattern and displays it on the e-ink screen.
"""
import sys
import asyncio
from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from dreader.hal_hardware import HardwareDisplayHAL
def create_test_image(width=1404, height=1872 ):
"""Create a test pattern image."""
print("Creating test image...")
# Create white background
img = Image.new('RGBA', (width, height), color='white')
draw = ImageDraw.Draw(img)
# Draw border
border_width = 10
draw.rectangle(
[(border_width, border_width),
(width - border_width, height - border_width)],
outline='black',
width=border_width
)
# Draw title
try:
font_large = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 80)
font_medium = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 50)
except:
font_large = ImageFont.load_default()
font_medium = ImageFont.load_default()
# Center text
title = "Hardware Display Test"
title_bbox = draw.textbbox((0, 0), title, font=font_large)
title_width = title_bbox[2] - title_bbox[0]
title_x = (width - title_width) // 2
draw.text((title_x, 100), title, fill='black', font=font_large)
# Instructions
instructions = [
"If you can see this, the display is working!",
"",
"Test pattern includes:",
"• Border around the screen",
"• Centered text",
"• Diagonal lines",
"• Corner markers"
]
y = 250
for line in instructions:
if line:
bbox = draw.textbbox((0, 0), line, font=font_medium)
line_width = bbox[2] - bbox[0]
x = (width - line_width) // 2
draw.text((x, y), line, fill='black', font=font_medium)
y += 70
# Draw diagonal lines
draw.line([(50, 50), (width-50, height-50)], fill='black', width=3)
draw.line([(width-50, 50), (50, height-50)], fill='black', width=3)
# Draw corner markers
marker_size = 100
# Top-left
draw.rectangle([(20, 20), (20 + marker_size, 20 + marker_size)],
fill='black')
draw.text((30, 30), "TL", fill='white', font=font_medium)
# Top-right
draw.rectangle([(width - 20 - marker_size, 20),
(width - 20, 20 + marker_size)],
fill='black')
draw.text((width - 100, 30), "TR", fill='white', font=font_medium)
# Bottom-left
draw.rectangle([(20, height - 20 - marker_size),
(20 + marker_size, height - 20)],
fill='black')
draw.text((30, height - 100), "BL", fill='white', font=font_medium)
# Bottom-right
draw.rectangle([(width - 20 - marker_size, height - 20 - marker_size),
(width - 20, height - 20)],
fill='black')
draw.text((width - 100, height - 100), "BR", fill='white', font=font_medium)
print(f"Test image created: {width}x{height} RGBA")
return img
async def main(args):
"""Test hardware display."""
print("=" * 60)
print("Hardware Display Test")
print("=" * 60)
print()
# Get VCOM from args
vcom = args.vcom if hasattr(args, 'vcom') else -1.65
print(f"Using VCOM: {vcom}V")
print()
# Create test image
test_image = create_test_image(1872, 1404)
# Save test image for reference
output_file = "test_pattern.png"
test_image.save(output_file)
print(f"Test pattern saved to: {output_file}")
print()
# Initialize hardware HAL
print("Initializing hardware HAL...")
hal = HardwareDisplayHAL(
width=1872,
height=1404,
vcom=vcom,
config_file="hardware_config.json"
)
print("Initializing hardware components...")
await hal.initialize()
print("✓ Hardware initialized")
print()
# Display the test image
print("Displaying test image on e-ink screen...")
print("(This may take a few seconds for the full refresh)")
print(f"Converting image from {test_image.mode} to grayscale for e-ink...")
# Convert RGBA to grayscale (L mode) for e-ink display
if test_image.mode == 'RGBA':
# Convert RGBA to RGB first (flatten alpha)
rgb_image = Image.new('RGB', test_image.size, (255, 255, 255))
rgb_image.paste(test_image, mask=test_image.split()[3]) # Use alpha as mask
test_image_gray = rgb_image.convert('L')
else:
test_image_gray = test_image.convert('L')
print(f"Image converted to {test_image_gray.mode} mode")
await hal.show_image(test_image_gray)
print("✓ Image displayed!")
print()
print("=" * 60)
print("SUCCESS!")
print("=" * 60)
print()
print("If you can see the test pattern on the screen, the")
print("hardware display is working correctly!")
print()
print("Check that you can see:")
print(" • Black border around the edges")
print(" • Title text centered at the top")
print(" • Diagonal lines crossing the screen")
print(" • Corner markers labeled TL, TR, BL, BR")
print()
print("Press Ctrl+C to exit")
print()
# Keep running so user can see the image
try:
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
print("\nCleaning up...")
await hal.cleanup()
print("Done!")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Test hardware display')
parser.add_argument('--vcom', type=float, default=-1.65,
help='VCOM voltage (check your display label, default: -1.65)')
args = parser.parse_args()
try:
asyncio.run(main(args))
except KeyboardInterrupt:
print("\nTest interrupted")
except Exception as e:
print(f"\nERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@ -0,0 +1,175 @@
#!/usr/bin/env python3
"""
Test script to render the library view and display it on hardware.
Combines library rendering with hardware display testing.
"""
import sys
import asyncio
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from dreader.library import LibraryManager
from dreader.hal_hardware import HardwareDisplayHAL
async def main(args):
"""Test library rendering on hardware display."""
library_path = args.library_path
output_path = "library_render_test.png"
vcom = args.vcom
print("=" * 60)
print("Library Rendering on Hardware Test")
print("=" * 60)
print(f"Library path: {library_path}")
print(f"VCOM: {vcom}V")
print(f"Output file: {output_path}")
print()
# Step 1: Create library manager and scan
print("Step 1: Creating library manager...")
library = LibraryManager(
library_path=library_path,
page_size=(1872, 1404)
)
print("Scanning library...")
library.scan_library()
print()
print(f"Found {len(library.books)} books:")
for i, book in enumerate(library.books[:10], 1): # Show first 10
print(f" {i}. {book['title']} by {book['author']}")
if len(library.books) > 10:
print(f" ... and {len(library.books) - 10} more")
print()
# Step 2: Create and render library table
print("Step 2: Creating library table (page 1)...")
table = library.create_library_table(page=0)
print(f"✓ Library table created: {table is not None}")
if table:
print(f" Table has {len(table.rows)} rows")
print()
print("Rendering library view...")
image = library.render_library()
if not image:
print("ERROR: No image rendered!")
print(f" library.library_table = {library.library_table}")
print(f" library.rendered_page = {library.rendered_page}")
return 1
print(f"✓ Library rendered: {image.size} {image.mode}")
# Check if image is not blank
import numpy as np
img_array = np.array(image)
unique_colors = len(np.unique(img_array.reshape(-1, img_array.shape[-1]), axis=0))
print(f" Image has {unique_colors} unique colors (blank would be ~1)")
# Sample some pixels to see what we have
print(f" Sample pixels:")
print(f" Top-left corner: {image.getpixel((10, 10))}")
print(f" Center: {image.getpixel((936, 702))}")
print(f" Bottom-right: {image.getpixel((1860, 1390))}")
print()
# Save for reference
print(f"Saving to {output_path}...")
image.save(output_path)
print(f"✓ Saved to {output_path}")
print()
# Step 3: Initialize hardware HAL
print("Step 3: Initializing hardware HAL...")
hal = HardwareDisplayHAL(
width=1872,
height=1404,
vcom=vcom,
config_file="hardware_config.json"
)
print("Initializing hardware components...")
await hal.initialize()
print("✓ Hardware initialized")
print()
# Step 4: Display on e-ink screen
print("Step 4: Displaying library on e-ink screen...")
print("(This may take a few seconds for the full refresh)")
print(f"Converting image from {image.mode} to grayscale for e-ink...")
# Convert to grayscale (L mode) for e-ink display
if image.mode == 'RGBA':
# Convert RGBA to RGB first (flatten alpha)
rgb_image = Image.new('RGB', image.size, (255, 255, 255))
rgb_image.paste(image, mask=image.split()[3]) # Use alpha as mask
image_gray = rgb_image.convert('L')
else:
image_gray = image.convert('L')
print(f"Image converted to {image_gray.mode} mode")
await hal.show_image(image_gray)
print("✓ Image displayed!")
print()
print("=" * 60)
print("SUCCESS!")
print("=" * 60)
print()
print("The library view should now be visible on your e-ink screen.")
print()
print(f"You can also view the saved PNG: {output_path}")
print()
print("Press Ctrl+C to exit")
print()
# Keep running so user can see the image
try:
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
print("\nCleaning up...")
await hal.cleanup()
print("Done!")
return 0
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description='Test library rendering on hardware display'
)
parser.add_argument(
'library_path',
nargs='?',
default='tests/data/library-epub',
help='Path to library directory (default: tests/data/library-epub)'
)
parser.add_argument(
'--vcom',
type=float,
default=-1.65,
help='VCOM voltage (check your display label, default: -1.65)'
)
args = parser.parse_args()
try:
exit_code = asyncio.run(main(args))
sys.exit(exit_code or 0)
except KeyboardInterrupt:
print("\nTest interrupted")
sys.exit(0)
except Exception as e:
print(f"\nERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

89
examples/test_library_render.py Executable file
View File

@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""
Test script to render the library view and save it as PNG.
This helps verify the rendering is working correctly.
"""
import sys
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from dreader.library import LibraryManager
def main():
"""Test library rendering and save as PNG."""
library_path = "tests/data/library-epub"
output_path = "library_render_test.png"
print("=" * 60)
print("Library Rendering Test")
print("=" * 60)
print(f"Library path: {library_path}")
print(f"Output file: {output_path}")
print()
# Create library manager
print("Creating library manager...")
library = LibraryManager(
library_path=library_path,
page_size=(1872, 1404)
)
# Scan library
print("Scanning library...")
library.scan_library()
print()
print(f"Found {len(library.books)} books:")
for book in library.books:
print(f" - {book['title']} by {book['author']}")
print()
# Create library table (renders the first page)
print("Creating library table (page 1)...")
library.create_library_table(page=0)
# Render the table
print("Rendering library view...")
image = library.render_library()
if image:
print(f"Image size: {image.size}")
print(f"Image mode: {image.mode}")
# Save as PNG
print(f"Saving to {output_path}...")
image.save(output_path)
print()
print("=" * 60)
print("SUCCESS!")
print("=" * 60)
print(f"Library view saved to: {output_path}")
print()
print("You can view the image with:")
print(f" xdg-open {output_path} # Linux")
print(f" open {output_path} # macOS")
print()
return 0
else:
print()
print("=" * 60)
print("ERROR: No image rendered")
print("=" * 60)
return 1
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as e:
print(f"\nERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

126
examples/test_simple_pattern.py Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""
Simplest possible test - half black, half white screen.
This verifies the display can show black pixels.
"""
import sys
import asyncio
from pathlib import Path
from PIL import Image, ImageDraw
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from dreader.hal_hardware import HardwareDisplayHAL
def create_simple_test():
"""Create a simple half-black, half-white test image."""
print("Creating simple test pattern...")
print("Left half: BLACK")
print("Right half: WHITE")
width, height = 1872, 1404
# Create grayscale image (L mode = 8-bit grayscale)
img = Image.new('L', (width, height), color=255) # Start with white
draw = ImageDraw.Draw(img)
# Draw left half black
draw.rectangle(
[(0, 0), (width // 2, height)],
fill=0 # 0 = black
)
print(f"Test image created: {width}x{height} grayscale")
print(f" Left half ({width//2}px): BLACK (0)")
print(f" Right half ({width//2}px): WHITE (255)")
return img
async def main(args):
"""Test hardware display with simple pattern."""
print("=" * 60)
print("Simple Display Test - Half Black, Half White")
print("=" * 60)
print()
vcom = args.vcom
print(f"Using VCOM: {vcom}V")
print()
# Create simple test image
test_image = create_simple_test()
# Save test image for reference
output_file = "simple_test.png"
test_image.save(output_file)
print(f"Test pattern saved to: {output_file}")
print()
# Initialize hardware HAL
print("Initializing hardware HAL...")
hal = HardwareDisplayHAL(
width=1872,
height=1404,
vcom=vcom,
config_file="hardware_config.json"
)
print("Initializing hardware components...")
await hal.initialize()
print("✓ Hardware initialized")
print()
# Display the test image
print("Displaying test pattern on e-ink screen...")
print("(This may take a few seconds for the full refresh)")
await hal.show_image(test_image)
print("✓ Image displayed!")
print()
print("=" * 60)
print("CHECK YOUR SCREEN:")
print("=" * 60)
print()
print("You should see:")
print(" • LEFT HALF: BLACK")
print(" • RIGHT HALF: WHITE")
print()
print("If you see this, the display is working!")
print("If the screen is all white, there may be a driver issue.")
print()
print("Press Ctrl+C to exit")
print()
# Keep running so user can see the image
try:
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
print("\nCleaning up...")
await hal.cleanup()
print("Done!")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Simple display test')
parser.add_argument('--vcom', type=float, default=-1.65,
help='VCOM voltage (check your display label, default: -1.65)')
args = parser.parse_args()
try:
asyncio.run(main(args))
except KeyboardInterrupt:
print("\nTest interrupted")
except Exception as e:
print(f"\nERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@ -5,8 +5,9 @@
"display": {
"width": 1872,
"height": 1404,
"vcom": -2.0,
"vcom": -1.7,
"spi_hz": 24000000,
"rotate": "CW",
"auto_sleep": true
},