Adding Support for New Devices
This guide explains how to extend the library to support additional Brother P-touch printers and tape types.
Adding a New Printer
Step 1: Gather Specifications
You need the following information from the Brother raster command reference:
USB Product ID - From the printer’s USB descriptor
Print head specifications:
Total pins in print head
Base resolution (DPI)
High resolution (DPI) if supported
Capability flags:
Auto-cut support
Half-cut support
Page number cuts support
Pin configuration for each tape width:
Left margin pins
Printable area pins
Right margin pins
Finding USB Product ID
Connect the printer and run:
# Linux
lsusb | grep Brother
# Output: Bus 001 Device 010: ID 04f9:20af Brother Industries, Ltd
# The product ID is 20af (0x20af in hex)
Or use Python:
import usb.core
# Find all Brother devices
devices = usb.core.find(find_all=True, idVendor=0x04f9)
for dev in devices:
print(f"Product ID: {hex(dev.idProduct)}")
print(f"Product: {dev.product}")
Step 2: Create Printer Class
Create a new class in src/ptouch/printers.py:
from ptouch.printer import LabelPrinter, TapeConfig
from ptouch.tape import (
Tape6mm,
Tape9mm,
Tape12mm,
Tape18mm,
Tape24mm,
)
class PTP710BT(LabelPrinter):
"""Brother PT-P710BT label printer.
Specifications:
- Resolution: 180 DPI (standard), 360 DPI (high)
- Print head: 128 pins
- Max tape width: 24mm
- Supports: Auto-cut, Half-cut
"""
# USB identification
USB_PRODUCT_ID = 0x209d # Replace with actual ID
# Print head specifications
TOTAL_PINS = 128
BYTES_PER_LINE = 16 # TOTAL_PINS / 8
RESOLUTION_DPI = 180
RESOLUTION_DPI_HIGH = 360
# Capability flags
SUPPORTS_AUTO_CUT = True
SUPPORTS_HALF_CUT = True
SUPPORTS_PAGE_NUMBER_CUTS = True
# Default settings
DEFAULT_USE_COMPRESSION = True
DEFAULT_AUTO_CUT = True
DEFAULT_HALF_CUT = True
DEFAULT_HIGH_RESOLUTION = False
DEFAULT_PAGE_NUMBER_CUTS = False
# Pin configuration for each tape width
# Values from Brother raster command reference
PIN_CONFIGS = {
Tape6mm: TapeConfig(
left_pins=48,
print_pins=32,
right_pins=48
),
Tape9mm: TapeConfig(
left_pins=39,
print_pins=50,
right_pins=39
),
Tape12mm: TapeConfig(
left_pins=29,
print_pins=70,
right_pins=29
),
Tape18mm: TapeConfig(
left_pins=8,
print_pins=112,
right_pins=8
),
Tape24mm: TapeConfig(
left_pins=0,
print_pins=128,
right_pins=0
),
}
Step 3: Export the Printer Class
Add to src/ptouch/__init__.py:
from .printers import (
# ... existing imports ...
PTP710BT, # Add your new printer
)
__all__ = [
# ... existing exports ...
"PTP710BT", # Add to __all__
]
Step 4: Add Tests
Create tests in tests/test_printers.py:
def test_ptp710bt_specifications():
"""Test PTP710BT printer specifications."""
printer = PTP710BT(mock_connection)
assert printer.USB_PRODUCT_ID == 0x209d
assert printer.TOTAL_PINS == 128
assert printer.RESOLUTION_DPI == 180
assert printer.RESOLUTION_DPI_HIGH == 360
assert printer.SUPPORTS_AUTO_CUT is True
assert printer.SUPPORTS_HALF_CUT is True
def test_ptp710bt_tape_configs():
"""Test tape configurations for PTP710BT."""
printer = PTP710BT(mock_connection)
# Test each tape size
config = printer.get_tape_config(Tape12mm)
assert config.left_pins == 29
assert config.print_pins == 70
assert config.right_pins == 29
assert config.total_pins == 128
def test_ptp710bt_printing():
"""Test basic printing with PTP710BT."""
printer = PTP710BT(mock_connection)
label = Label(sample_image, Tape12mm)
printer.print(label)
assert len(mock_connection.data) > 0
Step 5: Update Documentation
Add to the README.md supported printers table and update docs.
Example: P900 Series Printers
The P900 series printers share identical specifications, so they inherit from a common base:
class PTP900Series(LabelPrinter):
"""Base class for Brother PT-P900 series printers."""
TOTAL_PINS = 560
BYTES_PER_LINE = 70
RESOLUTION_DPI = 360
RESOLUTION_DPI_HIGH = 720
# ... rest of common config ...
class PTP900(PTP900Series):
"""Brother PT-P900 (USB only)."""
USB_PRODUCT_ID = 0x20af
class PTP900W(PTP900Series):
"""Brother PT-P900W (USB + WiFi)."""
USB_PRODUCT_ID = 0x20af # Same as P900
class PTP910BT(PTP900Series):
"""Brother PT-P910BT (USB + Bluetooth)."""
USB_PRODUCT_ID = 0x20af # Same as P900
class PTP950NW(PTP900Series):
"""Brother PT-P950NW (USB + WiFi + NFC)."""
USB_PRODUCT_ID = 0x20af # Same as P900
Adding a New Tape Type
Step 1: Determine Tape Specifications
You need:
Physical width in millimeters
Tape category (laminated, non-laminated, etc.)
Compatible printers
Step 2: Create Tape Class
Add to src/ptouch/tape.py:
class Tape48mm(Tape):
"""48mm laminated tape (TZe-481, etc.).
Compatible with larger industrial printers only.
"""
width_mm = 48
For non-laminated tape:
class Tape(ABC):
"""Base class for all tape types."""
width_mm: int
@property
@abstractmethod
def category(self) -> str:
"""Tape category identifier."""
pass
class NonTape(Tape):
"""Non-laminated (N) series tapes."""
@property
def category(self) -> str:
return "non-laminated"
class NonTape12mm(NonTape):
"""12mm non-laminated tape."""
width_mm = 12
Step 3: Add Pin Configuration
Update each compatible printer’s PIN_CONFIGS:
class PTP900(PTP900Series):
PIN_CONFIGS = {
# ... existing configs ...
Tape48mm: TapeConfig(
left_pins=0,
print_pins=680, # Example - check reference manual
right_pins=0
),
}
Finding Pin Configuration Values
Pin configurations come from the Brother raster command reference PDF for your printer model. Look for tables showing:
Tape width
Left margin pins
Effective print area pins
Right margin pins
The sum must equal TOTAL_PINS for the printer.
Step 4: Export and Test
Add to src/ptouch/__init__.py:
from .tape import (
# ... existing imports ...
Tape48mm,
)
__all__ = [
# ... existing exports ...
"Tape48mm",
]
Test with your printer:
def test_new_tape():
printer = PTP900(mock_connection)
label = Label(sample_image, Tape48mm)
printer.print(label)
Testing Your Changes
Unit Tests
Run the test suite:
pytest tests/
Ensure all existing tests still pass and new tests pass.
Real Hardware Testing
Test with actual printer:
from ptouch import ConnectionUSB, PTP710BT, TextLabel, Tape12mm
from PIL import ImageFont
# Test basic functionality
connection = ConnectionUSB()
printer = PTP710BT(connection)
label = TextLabel(
"Test Label",
Tape12mm,
font=ImageFont.load_default()
)
printer.print(label)
Test each tape size supported by the printer.
Contributing Back
If you add support for a new device, please consider contributing it back to the project.
See CONTRIBUTING.md for detailed guidelines on:
How to submit pull requests
Code style and testing requirements
Documentation standards
Review process
Common Issues
Wrong Pin Configuration
Symptom: Labels print with incorrect alignment or clipped edges.
Solution: Double-check pin configuration values in the Brother reference manual. Ensure left_pins + print_pins + right_pins == TOTAL_PINS.
USB Product ID Conflicts
Symptom: Wrong printer class is selected.
Solution: Many Brother printers share the same USB product ID. The library cannot distinguish between them automatically. Users must select the correct class.
Unsupported Features
Symptom: Features work on some printers but not others.
Solution: Set capability flags correctly:
SUPPORTS_AUTO_CUT = False # If printer doesn't support auto-cut
SUPPORTS_HALF_CUT = False # If printer doesn't support half-cut
The library will raise an error if unsupported features are requested.
Resolution Confusion
Symptom: High resolution mode doesn’t work or produces wrong output.
Solution: Check if printer actually supports high resolution:
RESOLUTION_DPI_HIGH = 0 # Set to 0 if not supported
Resources
Brother Developer Portal - Raster command reference manuals
Printer Module - API documentation for LabelPrinter class
Tape Module - API documentation for Tape classes
GitHub Issues - Ask for help
Need Help?
If you’re adding support for a device and need assistance:
Open a GitHub issue with your printer model
Include USB vendor/product ID
Link to the printer’s raster command reference if available
Describe what you’ve tried
The community can help guide you through the process.