### Install niimprint with Poetry or Pip Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Install the niimprint library using either poetry or pip. Poetry is the recommended method. ```bash # Using poetry (recommended) poetry install # Using pip with requirements.txt pip install -r requirements.txt ``` -------------------------------- ### Install Niimprint with Poetry or Pip Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/INDEX.md Install the library using either Poetry for dependency management or pip with a requirements file. Ensure Python 3.11 or later is installed. ```bash # Install with poetry poetry install ``` ```bash # Or with pip pip install -r requirements.txt ``` ```bash # Python requirement: 3.11+ (tested on 3.11) python --version ``` ```bash # Test installation python -c "import niimprint; print('Success')" ``` -------------------------------- ### Device Status Structure Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/types.md Shows how to get and interpret the device's current status, including paper and RFID reader states. Requires initializing a PrinterClient with a transport. ```python from niimprint import SerialTransport, PrinterClient printer = PrinterClient(SerialTransport()) status = printer.heartbeat() if status['paperstate'] is not None: print(f"Paper present: {status['paperstate']}") ``` -------------------------------- ### CLI Example: Automatic Density Capping Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Demonstrates automatic density capping for printer models that have a maximum density limit. For example, B18 will cap density 5 to 3. ```bash # Print with automatic density capping (B18 receives density 5, capped to 3) python -m niimprint -m b18 -c usb -i label.png -d 5 # Will be automatically reduced to 3 ``` -------------------------------- ### CLI Example: Print with Verbose Logging Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Illustrates how to enable verbose logging for debugging purposes when printing an image. ```bash # Print with verbose logging python -m niimprint -m b21 -c usb -i label.png -v ``` -------------------------------- ### CLI Example: Print on Windows via COM Port Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Shows how to print on a Windows system using a specified COM port for USB connection. ```bash # Print on Windows via COM port python -m niimprint -m b21 -c usb -a COM3 -i label.png ``` -------------------------------- ### Niimbot Heartbeat Command Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Example of a HEARTBEAT command (Type 0xDC) and its serialized format, including type, length, data, and checksum. ```text 55 55 DC 01 01 DC AA AA ↑ ↑ ↑ ↑ Type Len Data Checksum(DC^01^01=DC) ``` -------------------------------- ### CLI Example: Print on B21 via Bluetooth with Max Density Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Shows how to print an image on a B21 model printer using Bluetooth, specifying the MAC address and maximum density. ```bash # Print on B21 via Bluetooth with maximum density python -m niimprint -m b21 -c bluetooth -a "E2:E1:08:03:09:87" -d 5 -i label.png ``` -------------------------------- ### RFID Data Structure Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/types.md Demonstrates how to retrieve and access RFID data from the printer. Requires initializing a PrinterClient with a transport. ```python from niimprint import SerialTransport, PrinterClient printer = PrinterClient(SerialTransport()) rfid = printer.get_rfid() if rfid: print(f"UUID: {rfid['uuid']}") print(f"Used: {rfid['used_len']}/{rfid['total_len']} bytes") ``` -------------------------------- ### Niimbot SET_DIMENSION Request Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Example of setting label dimensions (120px height, 240px width) using the SET_DIMENSION command (Type 0x13). ```text Type: 0x13 Data: 00 78 00 F0 (0x0078=120, 0x00F0=240) ``` -------------------------------- ### CLI Example: Print on D11 via Specified Serial Port Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Demonstrates printing on a D11 model printer using USB, explicitly specifying the serial device path. ```bash # Print on D11 via specified serial port python -m niimprint -m d11 -c usb -a /dev/ttyACM0 -i small_label.png ``` -------------------------------- ### BluetoothTransport Implementation Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BaseTransport.md Instantiates BluetoothTransport for wireless communication and initializes a PrinterClient. Requires the Bluetooth device's address. ```python from niimprint import BluetoothTransport, PrinterClient transport = BluetoothTransport(address="E2:E1:08:03:09:87") printer = PrinterClient(transport) ``` -------------------------------- ### SerialTransport Implementation Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BaseTransport.md Instantiates SerialTransport for USB/serial communication and initializes a PrinterClient with it. Supports auto-detection of the serial port. ```python from niimprint import SerialTransport, PrinterClient transport = SerialTransport(port="/dev/ttyACM0") printer = PrinterClient(transport) ``` -------------------------------- ### Print Status Structure Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/types.md Illustrates how to retrieve the current printing progress. Requires initializing a PrinterClient with a transport. ```python from niimprint import SerialTransport, PrinterClient printer = PrinterClient(SerialTransport()) status = printer.get_print_status() print(f"Progress: {status['progress1']}%") ``` -------------------------------- ### CLI Example: Print on B21 via USB with Rotation Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Demonstrates printing an image on a B21 model printer using a USB connection with 90-degree clockwise rotation. ```bash # Print on B21 via USB with 90-degree rotation python -m niimprint -m b21 -c usb -r 90 -i label.png ``` -------------------------------- ### Niimbot IMAGE_DATA Request Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Example of sending image line data using the IMAGE_DATA command (Type 0x85), including header and pixel data format. ```text Type: 0x85 Data: [0x00, 0x00, # Line 0 0x00, 0x00, 0x00, # Counts/reserved 0xFF, 0xFF, ..., 0x00] # 30 bytes of pixel data (all black then white) ``` -------------------------------- ### Importing Niimprint Components Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/types.md Provides examples of how to import necessary classes and enums from the niimprint package, including from the package root and specific modules. ```python # From package root from niimprint import SerialTransport, BluetoothTransport, PrinterClient # From printer module from niimprint.printer import ( InfoEnum, RequestCodeEnum, BaseTransport, SerialTransport, BluetoothTransport, PrinterClient, ) # From packet module from niimprint.packet import NiimbotPacket ``` -------------------------------- ### Initialize PrinterClient with SerialTransport Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Instantiate a PrinterClient using a SerialTransport. This example shows both auto-detection of a USB serial port and explicit port specification. ```python from niimprint import SerialTransport, PrinterClient # Auto-detect USB serial port transport = SerialTransport() client = PrinterClient(transport) # Or specify explicit port transport = SerialTransport(port="/dev/ttyACM0") client = PrinterClient(transport) ``` -------------------------------- ### Get Device Information with PrinterClient Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Retrieve various pieces of information from the printer using the get_info method and InfoEnum. Examples include battery level, device serial number, and software version. ```python from niimprint import SerialTransport, PrinterClient from niimprint.printer import InfoEnum printer = PrinterClient(SerialTransport()) # Get device info battery = printer.get_info(InfoEnum.BATTERY) print(f"Battery level: {battery}") serial = printer.get_info(InfoEnum.DEVICESERIAL) print(f"Device serial: {serial}") version = printer.get_info(InfoEnum.SOFTVERSION) print(f"Software version: {version}") ``` -------------------------------- ### CLI Example: Print on D11 via USB Auto-detect Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Illustrates printing on a D11 model printer using USB, relying on automatic detection of the serial port. ```bash # Print on D11 via USB auto-detect (serial port) python -m niimprint -m d11 -c usb -i small_label.png ``` -------------------------------- ### Initialize Print Session Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Starts a print session. This method must be called before sending any image data to the printer. ```python printer.start_print() # Now send image data... ``` -------------------------------- ### Print Image via Command Line Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/README.md Examples of printing an image using the niimprint command-line interface. Demonstrates auto-detection, Bluetooth connection with rotation and density, and explicit serial port connection. ```bash # Simple: auto-detect USB port on B21 python -m niimprint -i label.png ``` ```bash # Bluetooth on B21 with rotation and density python -m niimprint -m b21 -c bluetooth \ -a "E2:E1:08:03:09:87" -r 90 -d 5 -i label.png ``` ```bash # Explicit serial port python -m niimprint -m b21 -c usb -a /dev/ttyACM0 -i label.png ``` -------------------------------- ### start_page_print Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Starts the printing process for a single page or label. ```APIDOC ## start_page_print() ### Description Starts the printing process for a single page or label. ### Method `start_page_print` ### Response #### Success Response - **bool**: True if successful, False otherwise. ### Example ```python printer.start_page_print() # Set dimensions and send image data ``` ``` -------------------------------- ### Protocol Enhancement Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/MODULE_OVERVIEW.md Demonstrates how to add new command methods to PrinterClient by following the existing _transceive() pattern. This involves defining a new method that uses _transceive() with a custom request code and processing the response. ```python def custom_command(self): pkt = self._transceive(RequestCodeEnum.CUSTOM, data) # Process response ``` -------------------------------- ### Transport Layer Abstraction Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/MODULE_OVERVIEW.md Demonstrates how to use PrinterClient with different transport implementations like SerialTransport or BluetoothTransport. This allows swapping connection methods without altering the PrinterClient logic. ```python transport = SerialTransport() # or BluetoothTransport(addr) printer = PrinterClient(transport) printer.print_image(image) ``` -------------------------------- ### Start Page Printing Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Initiates the printing process for a single page or label. Call this before setting dimensions or sending image data for the page. ```python printer.start_page_print() # Set dimensions and send image data ``` -------------------------------- ### Printer Context Manager Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Use this context manager to ensure proper setup and cleanup of printer resources. It handles the initialization of SerialTransport and PrinterClient. ```python from niimprint import SerialTransport, PrinterClient from PIL import Image from contextlib import contextmanager @contextmanager def get_printer(): """Context manager for printer operations.""" transport = SerialTransport() printer = PrinterClient(transport) try: yield printer finally: # Cleanup if needed pass # Usage with get_printer() as printer: image = Image.open("label.png") printer.print_image(image, density=4) print("Print complete and resources cleaned up") ``` -------------------------------- ### Custom Transport Implementation Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BaseTransport.md Provides a template for creating a custom transport by inheriting from BaseTransport and implementing the read and write methods for a specific communication endpoint. ```python from niimprint.printer import BaseTransport, PrinterClient class CustomTransport(BaseTransport): def __init__(self, endpoint): self.endpoint = endpoint # Setup connection def read(self, length: int) -> bytes: """Read length bytes from your endpoint.""" # Implementation specific to your transport data = self.endpoint.recv(length) return data def write(self, data: bytes): """Write data to your endpoint.""" # Implementation specific to your transport self.endpoint.send(data) # Usage custom = CustomTransport(my_endpoint) printer = PrinterClient(custom) ``` -------------------------------- ### Handle Invalid Packet Start Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/errors.md Catch AssertionError if received packet data does not start with the expected sync marker `0x55 0x55`. This indicates corrupted data or a packet boundary issue. ```python assert pkt[:2] == b"\x55\x55" ``` ```python from niimprint.packet import NiimbotPacket try: pkt = NiimbotPacket.from_bytes(b"\x00\x00\x01\x01...") except AssertionError: print("Received invalid packet - corrupted data or misalignment") ``` -------------------------------- ### Packet Protocol Wrapper Example Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/MODULE_OVERVIEW.md Shows the creation of a NiimbotPacket object and its automatic serialization into a binary format, including sync markers, checksum, and end markers. This abstracts raw byte manipulation for the PrinterClient. ```python # High-level pkt = NiimbotPacket(0xDC, b"\x01") # HEARTBEAT # Automatically serializes to: # [0x55][0x55][0xDC][0x01][0x01][checksum][0xAA][0xAA] binary = pkt.to_bytes() ``` -------------------------------- ### Get Bluetooth Device Info on Linux Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BluetoothTransport.md Use `bluetoothctl` on Linux to retrieve detailed information about a specific Bluetooth device using its MAC address. ```bash # Get detailed info on a specific address bluetoothctl info E2:E1:08:03:09:87 ``` -------------------------------- ### Custom Transport Implementation Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BaseTransport.md Example of how to implement a custom transport by inheriting from BaseTransport. This allows for integration with various communication methods like network sockets or file I/O. ```APIDOC ## Custom Transport Implementation ### Description To create a custom transport (e.g., for network, file, or simulator): ### Example Usage ```python from niimprint.printer import BaseTransport, PrinterClient class CustomTransport(BaseTransport): def __init__(self, endpoint): self.endpoint = endpoint # Setup connection def read(self, length: int) -> bytes: """Read length bytes from your endpoint.""" # Implementation specific to your transport data = self.endpoint.recv(length) return data def write(self, data: bytes): """Write data to your endpoint.""" # Implementation specific to your transport self.endpoint.send(data) # Usage custom = CustomTransport(my_endpoint) printer = PrinterClient(custom) ``` ``` -------------------------------- ### Print Image via Python Code Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/README.md Example of printing an image using the niimprint Python library. Requires importing SerialTransport, PrinterClient, and PIL.Image. Connects to the printer and then loads and prints the image with specified density. ```python from niimprint import SerialTransport, PrinterClient from PIL import Image # Connect to printer printer = PrinterClient(SerialTransport()) # Load and print image image = Image.open("label.png") printer.print_image(image, density=4) ``` -------------------------------- ### Analyzing Packet Bytes Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Provides a Python code example for parsing a logged packet string into a NiimbotPacket object for analysis. ```APIDOC ## Analyzing Packet Bytes ```python # Parse a logged packet hex_string = "55:55:01:01:01:xx:aa:aa" bytes_data = bytes.fromhex(hex_string.replace(":", "")) packet = NiimbotPacket.from_bytes(bytes_data) print(f"Type: {packet.type}, Data: {packet.data.hex()}") ``` ``` -------------------------------- ### Handling Protocol Errors Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Provides Python code examples for handling specific protocol error codes, such as device errors or unimplemented response types. ```python if packet.type == 219: raise ValueError("Device error") elif packet.type == 0: raise NotImplementedError("Unknown response") ``` -------------------------------- ### Handle Multiple Serial Ports Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/errors.md When auto-detecting serial ports, if multiple are found, a RuntimeError is raised. This example shows how to catch this error and explicitly select a port. ```python if len(all_ports) > 1: msg = "Too many serial ports, please select specific one:" for port, desc, hwid in all_ports: msg += f"\n- {port} : {desc} [{hwid}]" raise RuntimeError(msg) ``` ```python from niimprint import SerialTransport try: transport = SerialTransport() except RuntimeError as e: print("Multiple ports found:") print(e) # Explicitly select one transport = SerialTransport(port="/dev/ttyACM0") ``` -------------------------------- ### Print Image on D11 Printer Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Example of printing an image on a D11 printer with density level 3. The D11 model has a limited density range of 1 to 3. ```python from niimprint import SerialTransport, PrinterClient from PIL import Image printer = PrinterClient(SerialTransport()) image = Image.open("96x48_label.png") # Typical D11 size: 12x6mm # D11 limited to density 1-3 printer.print_image(image, density=3) ``` -------------------------------- ### Print Label via Bluetooth Source: https://github.com/andbondstyle/niimprint/blob/main/readme.md Example command to print an 80x50 mm label using a B21 printer connected via Bluetooth. Specify the Bluetooth MAC address, rotation, and image path. ```bash python niimprint -c bluetooth -a "E2:E1:08:03:09:87" -r 90 -i examples/B21_80x50mm_640x384px.png ``` -------------------------------- ### Print Label via USB Source: https://github.com/andbondstyle/niimprint/blob/main/readme.md Example command to print a 30x15 mm label using a B21 printer connected via USB. Specify the serial port, rotation, and image path. ```bash python niimprint -c usb -a /dev/ttyACM0 -r 90 -i examples/B21_30x15mm_240x120px.png ``` -------------------------------- ### Get Print Progress Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Query the printer to get the current status of an ongoing print job. ```python printer.get_print_status() ``` -------------------------------- ### Programmatic Configuration: PrinterClient Initialization Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Demonstrates initializing the PrinterClient with a configured transport (SerialTransport in this case) and loading an image using Pillow. ```python from niimprint import PrinterClient, SerialTransport from PIL import Image transport = SerialTransport() printer = PrinterClient(transport) # Load image image = Image.open("label.png") ``` -------------------------------- ### Send Heartbeat and Get Printer Status Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Send a heartbeat signal to the printer to get its current status, including power level and paper state. The returned dictionary may contain optional keys depending on the printer model. ```python from niimprint import SerialTransport, PrinterClient printer = PrinterClient(SerialTransport()) status = printer.heartbeat() print(f"Power level: {status['powerlevel']}") print(f"Paper state: {status['paperstate']}") ``` -------------------------------- ### Get Battery Level Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Retrieve the printer's battery level using the get_info method with the BATTERY enum. ```python printer.get_info(InfoEnum.BATTERY) ``` -------------------------------- ### Protocol Errors Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Lists common protocol errors with their corresponding codes and meanings, and provides example handling in Python. ```APIDOC ## Protocol Errors | Code | Hex | Meaning | |------|-----|---------| | 219 | 0xDB | Device error response | | 0 | 0x00 | Unimplemented/unknown response type | ### Handling ```python if packet.type == 219: raise ValueError("Device error") elif packet.type == 0: raise NotImplementedError("Unknown response") ``` ``` -------------------------------- ### CustomTransport Implementation Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BaseTransport.md An example of a custom BaseTransport subclass handling socket timeouts and errors during read and write operations. ```python class CustomTransport(BaseTransport): def read(self, length: int) -> bytes: try: return self.socket.recv(length) except socket.timeout: return b"" # Return empty on timeout except socket.error as e: raise OSError(f"Read failed: {e}") def write(self, data: bytes) -> int: try: return self.socket.send(data) except socket.error as e: raise OSError(f"Write failed: {e}") ``` -------------------------------- ### Simple Print via CLI Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Use the command-line interface to print an image file using the default settings. ```bash python -m niimprint -i label.png ``` -------------------------------- ### Niimprint CLI Help Source: https://github.com/andbondstyle/niimprint/blob/main/readme.md Displays the available command-line options for the niimprint tool, including printer model, connection type, address, density, rotation, and image path. ```bash python niimprint --help ``` -------------------------------- ### Get Device Serial Number Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Obtain the unique serial number of the printer device by calling get_info with the DEVICESERIAL enum. ```python printer.get_info(InfoEnum.DEVICESERIAL) ``` -------------------------------- ### Transport Abstraction in Python Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/README.md Demonstrates the transport abstraction in the niimprint library, allowing seamless switching between USB and Bluetooth connections. The PrinterClient works identically with either transport. ```python # Use either — code is identical transport = SerialTransport(port="/dev/ttyACM0") transport = BluetoothTransport(address="E2:E1:08:03:09:87") printer = PrinterClient(transport) # Works with either ``` -------------------------------- ### Initialize PrinterClient with Serial Transport Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/INDEX.md Use the PrinterClient class as the main entry point for printer control. Initialize it with a SerialTransport instance for USB connections. ```python from niimprint import PrinterClient, SerialTransport printer = PrinterClient(SerialTransport()) printer.print_image(image, density=3) ``` -------------------------------- ### Print with Custom Density and Rotation via CLI Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Specify the printer model, connection type, density, rotation, and image file for printing. ```bash python -m niimprint -m b21 -c usb -d 5 -r 90 -i label.png ``` -------------------------------- ### start_print Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Initializes a print session. This method must be called before sending any image data. ```APIDOC ## start_print() ### Description Initializes a print session. This method must be called before sending any image data. ### Method `start_print` ### Response #### Success Response - **bool**: True if successful, False otherwise. ### Example ```python printer.start_print() # Now send image data... ``` ``` -------------------------------- ### Get Print Status Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Retrieves the current status of the print job, including page number and progress indicators. Useful for monitoring print progress. ```python status = printer.get_print_status() print(f"Page: {status['page']}, Progress: {status['progress1']}%") ``` -------------------------------- ### Packet Encapsulation with NiimbotPacket Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/README.md Illustrates packet encapsulation using the NiimbotPacket class. Shows how to work with packet objects at a high level and how the class handles automatic serialization, including checksum and markers, to bytes. ```python # High-level: work with objects pkt = NiimbotPacket(0xDC, b"\x01") # Low-level: automatic serialization binary = pkt.to_bytes() # Includes checksum and markers ``` -------------------------------- ### Handle Serial Port Detection Failure Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/errors.md Raises a RuntimeError when no serial ports are detected during automatic detection. Provides an example of how to explicitly specify the port. ```python if len(all_ports) == 0: raise RuntimeError("No serial ports detected") ``` ```python from niimprint import SerialTransport try: transport = SerialTransport() except RuntimeError as e: print(f"Connection error: {e}") # Provide explicit port transport = SerialTransport(port="/dev/ttyACM0") ``` -------------------------------- ### Manual Packet Creation Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Demonstrates how to manually create and serialize a NiimbotPacket object using the niimprint library. ```APIDOC ## Manual Packet Creation ```python from niimprint.packet import NiimbotPacket # Create a command pkt = NiimbotPacket(0x01, b"\x01") print(pkt.to_bytes().hex()) # See serialized form ``` ``` -------------------------------- ### Print Image on B21 Printer Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Example of printing an image on a B21 printer with maximum density. The B21 model supports density levels from 1 to 5. ```python from niimprint import SerialTransport, PrinterClient from PIL import Image printer = PrinterClient(SerialTransport()) image = Image.open("640x384_label.png") # Typical B21 size: 80x48mm # B21 supports full density range 1-5 printer.print_image(image, density=5) ``` -------------------------------- ### Load, Optimize, and Print Image Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Loads an image, converts it to grayscale, resizes it if it exceeds the maximum width, and then prints it with density 5. Ensure the image is compatible with Niimprint printers. ```python from PIL import Image from niimprint import SerialTransport, PrinterClient # Load and optimize image image = Image.open("label.png") # Convert to grayscale for better control image = image.convert("L") # Optionally rotate programmatically # (or use CLI --rotate option) # image = image.rotate(-90) # Rotate 90 degrees counter-clockwise # Ensure width is within limits max_width = 384 # For B21/B1/B18 if image.width > max_width: # Resize maintaining aspect ratio ratio = max_width / image.width new_height = int(image.height * ratio) image = image.resize((max_width, new_height), Image.Resampling.LANCZOS) # Print printer = PrinterClient(SerialTransport()) printer.print_image(image, density=5) ``` -------------------------------- ### Query Device Information Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Retrieve various pieces of information from the printer, such as battery level, serial number, and software version. Uses the InfoEnum for specifying which info to get. ```python from niimprint import SerialTransport, PrinterClient from niimprint.printer import InfoEnum printer = PrinterClient(SerialTransport()) # Get device info battery = printer.get_info(InfoEnum.BATTERY) print(f"Battery: {battery}") serial = printer.get_info(InfoEnum.DEVICESERIAL) print(f"Serial: {serial}") version = printer.get_info(InfoEnum.SOFTVERSION) print(f"Software version: {version}") ``` -------------------------------- ### Print via Bluetooth using CLI Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Print an image file via Bluetooth by specifying the model, connection type, and Bluetooth address. ```bash python -m niimprint -m b21 -c bluetooth -a "E2:E1:08:03:09:87" -i label.png ``` -------------------------------- ### Manually Creating Niimprint Packets Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Shows how to create a NiimbotPacket object programmatically and serialize it into its byte representation for sending. ```python from niimprint.packet import NiimbotPacket # Create a command pkt = NiimbotPacket(0x01, b"\x01") print(pkt.to_bytes().hex()) # See serialized form ``` -------------------------------- ### Configure Programmatic Logging Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Sets up Python's logging module to display DEBUG level messages from Niimprint operations. This allows for detailed tracing of library behavior. ```python import logging from niimprint import SerialTransport, PrinterClient # Set up logging logging.basicConfig( level=logging.DEBUG, # or logging.INFO format="%(levelname)s | %(module)s:%(funcName)s:%(lineno)d - %(message)s" ) # Now all niimprint operations will be logged printer = PrinterClient(SerialTransport()) ``` -------------------------------- ### RequestCodeEnum Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/types.md Protocol command codes for the Niimbot printer communication protocol. These codes are used for various operations like getting information, setting parameters, and managing print jobs. ```APIDOC ## RequestCodeEnum ### Description Protocol command codes for the Niimbot printer communication protocol. These codes are used for various operations like getting information, setting parameters, and managing print jobs. ### Enum Values | Name | Decimal | Hex | Description | |------|---------|-----|-------------| | GET_INFO | 64 | 0x40 | Query device information (battery, version, serial, etc.). | | GET_RFID | 26 | 0x1A | Read RFID tag data from loaded label. | | HEARTBEAT | 220 | 0xDC | Send heartbeat and retrieve device status. | | SET_LABEL_TYPE | 35 | 0x23 | Configure label type. | | SET_LABEL_DENSITY | 33 | 0x21 | Set print density level. | | START_PRINT | 1 | 0x01 | Initialize print session. | | END_PRINT | 243 | 0xF3 | Finalize print and wait for completion. | | START_PAGE_PRINT | 3 | 0x03 | Begin printing a single page/label. | | END_PAGE_PRINT | 227 | 0xE3 | Finish printing current page/label. | | ALLOW_PRINT_CLEAR | 32 | 0x20 | Clear print buffer (may not be supported). | | SET_DIMENSION | 19 | 0x13 | Set label dimensions (height and width in pixels). | | SET_QUANTITY | 21 | 0x15 | Set number of copies to print. | | GET_PRINT_STATUS | 163 | 0xA3 | Retrieve current print progress. | ### Usage These values are used internally by `PrinterClient` methods and when working directly with `NiimbotPacket` objects: ```python from niimprint.printer import RequestCodeEnum from niimprint.packet import NiimbotPacket # Create a heartbeat packet pkt = NiimbotPacket(RequestCodeEnum.HEARTBEAT, b"\x01") # Or use the numeric value directly pkt = NiimbotPacket(0xDC, b"\x01") # HEARTBEAT = 220 = 0xDC ``` ``` -------------------------------- ### get_info Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Retrieves specific device information based on a provided key. The return type of the information varies depending on the key requested. ```APIDOC ## get_info ### get_info(key) Retrieve device information by key. Returns different types based on the requested key. #### Parameters - **key** (InfoEnum) - Required - Information type to retrieve (e.g., BATTERY, SOFTVERSION, DEVICESERIAL). #### Return type Depends on key: - `InfoEnum.DEVICESERIAL`: returns hex string - `InfoEnum.SOFTVERSION`: returns float (version / 100) - `InfoEnum.HARDVERSION`: returns float (version / 100) - Other keys: returns integer - Returns None if query fails after retries #### Example ```python from niimprint import SerialTransport, PrinterClient from niimprint.printer import InfoEnum printer = PrinterClient(SerialTransport()) battery = printer.get_info(InfoEnum.BATTERY) print(f"Battery level: {battery}") serial = printer.get_info(InfoEnum.DEVICESERIAL) print(f"Device serial: {serial}") ``` ``` -------------------------------- ### Handle Image Width Exceeding Printer Limits Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/errors.md Raises an AssertionError if the image width in pixels exceeds the maximum supported by the printer model. Includes example handling for resizing. ```python assert image.width <= max_width_px, f"Image width too big for {model.upper()}" ``` ```python from PIL import Image from niimprint import SerialTransport, PrinterClient printer = PrinterClient(SerialTransport()) image = Image.open("large_label.png") try: printer.print_image(image) except AssertionError as e: print(f"Image too wide: {e}") # Resize image image.thumbnail((384, 1000), Image.Resampling.LANCZOS) printer.print_image(image) ``` -------------------------------- ### Scan for Bluetooth Devices on Linux Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BluetoothTransport.md Use the `bluetoothctl` utility on Linux to scan for discoverable Bluetooth devices and list their MAC addresses. ```bash # List available Bluetooth devices bluetoothctl scan on ``` -------------------------------- ### niimprint CLI Command Reference Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/INDEX.md This snippet shows the available command-line options for the niimprint tool. Use it to control printer model, connection type, image path, and other settings. ```bash python -m niimprint [OPTIONS] Options: -m, --model [b1|b18|b21|d11|d110] Printer model (default: b21) -c, --conn [usb|bluetooth] Connection type (default: usb) -a, --addr TEXT MAC address or serial port -d, --density [1-5] Print density (default: 5) -r, --rotate [0|90|180|270] Image rotation (default: 0) -i, --image PATH Image file (required) -v, --verbose Enable debug logging --help Show help ``` -------------------------------- ### Enable Verbose Logging via CLI Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/configuration.md Enables detailed logging output, including packet traces and function call locations, when running Niimprint from the command line. Use the --verbose flag. ```bash # Enable verbose (DEBUG level) logging python -m niimprint -i label.png --verbose # Or combine with other options python -m niimprint -m b21 -c usb -i label.png -v ``` -------------------------------- ### Initialize BluetoothTransport and PrinterClient Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BluetoothTransport.md Connect to a Niimbot printer using its Bluetooth MAC address and initialize a PrinterClient for printing operations. Ensure the printer's MAC address is correctly formatted. ```python from niimprint import BluetoothTransport, PrinterClient # Connect to printer with known MAC address address = "E2:E1:08:03:09:87" transport = BluetoothTransport(address) printer = PrinterClient(transport) printer.print_image(image, density=4) ``` -------------------------------- ### PrinterClient with BaseTransport Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BaseTransport.md Demonstrates how PrinterClient utilizes a BaseTransport implementation for reading and writing data. ```python class PrinterClient: def __init__(self, transport: BaseTransport): self._transport = transport # ... def _recv(self): # Uses transport.read() self._packetbuf.extend(self._transport.read(1024)) # ... def _send(self, packet): # Uses transport.write() self._transport.write(packet.to_bytes()) ``` -------------------------------- ### Handle Serial Port Connection Failure Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/errors.md Catch pyserial's SerialException when a serial port cannot be opened. This might be due to the port being in use, non-existent, or permission issues. The example shows how to retry with a different port. ```python self._serial = serial.Serial(port=port, baudrate=115200, timeout=0.5) ``` ```python from niimprint import SerialTransport import serial try: transport = SerialTransport(port="/dev/ttyACM0") except serial.SerialException as e: print(f"Serial port error: {e}") # Try different port transport = SerialTransport(port="/dev/ttyUSB0") ``` -------------------------------- ### BluetoothTransport Constructor Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/BluetoothTransport.md Initializes a Bluetooth RFCOMM transport connection to a Niimbot printer using its MAC address. ```APIDOC ## BluetoothTransport(address) ### Description Initializes a Bluetooth RFCOMM transport connection to a Niimbot printer. ### Parameters #### Path Parameters - **address** (str) - Required - Bluetooth MAC address of the printer in format "XX:XX:XX:XX:XX:XX" (case-insensitive). ### Raises: - OSError/socket.error: if Bluetooth device cannot be found or connection fails - Exception: on other socket/connection failures ### Example: ```python from niimprint import BluetoothTransport, PrinterClient # Connect to printer with known MAC address address = "E2:E1:08:03:09:87" transport = BluetoothTransport(address) printer = PrinterClient(transport) printer.print_image(image, density=4) ``` ``` -------------------------------- ### Handle Bluetooth Connection Failure Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/errors.md Catch OSError or generic Exception when a Bluetooth connection fails. This can occur if the device is off, not paired, or the MAC address is incorrect. The example suggests trying an alternative MAC address format. ```python self._sock = socket.socket( socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM, ) self._sock.connect((address, 1)) ``` ```python from niimprint import BluetoothTransport, PrinterClient try: transport = BluetoothTransport("E2:E1:08:03:09:87") except (OSError, Exception) as e: print(f"Bluetooth connection failed: {e}") print("Try the rotated MAC address variant:") print("E.g., if E2:E1:08:03:09:87 fails, try 08:03:09:E2:E1:87") ``` -------------------------------- ### Usage of InfoEnum for Printer Queries Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/types.md Demonstrates how to use InfoEnum members to retrieve specific printer details like battery level, serial number, and software version. ```python from niimprint import SerialTransport, PrinterClient from niimprint.printer import InfoEnum printer = PrinterClient(SerialTransport()) # Get battery level battery = printer.get_info(InfoEnum.BATTERY) # Get device serial (returns hex string) serial = printer.get_info(InfoEnum.DEVICESERIAL) # Get software version (returns float, e.g., 2.15 for value 215) version = printer.get_info(InfoEnum.SOFTVERSION) ``` -------------------------------- ### PrinterClient Constructor Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Initializes a new PrinterClient instance. It requires a transport layer instance, which can be either a SerialTransport or BluetoothTransport. ```APIDOC ## PrinterClient Constructor ### PrinterClient(transport) Initializes a new PrinterClient instance. #### Parameters - **transport** (BaseTransport) - Required - Transport layer instance (SerialTransport or BluetoothTransport) #### Example ```python from niimprint import SerialTransport, PrinterClient transport = SerialTransport() client = PrinterClient(transport) ``` ``` -------------------------------- ### Print Image with PrinterClient Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/PrinterClient.md Print a PIL Image using the PrinterClient. Allows specifying print density. Ensure the image is loaded and the printer client is initialized. ```python from PIL import Image from niimprint import SerialTransport, PrinterClient transport = SerialTransport() printer = PrinterClient(transport) # Load and print image img = Image.open("label.png") printer.print_image(img, density=4) # With lower density printer.print_image(img, density=2) ``` -------------------------------- ### Niimprint Package Structure Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/MODULE_OVERVIEW.md Illustrates the directory and file organization of the niimprint package, indicating the purpose of each file. ```text niimprint/ ├── __init__.py (Package entry point, re-exports public API) ├── __main__.py (CLI command implementation) ├── printer.py (Core printer client and transport layers) └── packet.py (Low-level packet serialization) ``` -------------------------------- ### Initialize BluetoothTransport Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/INDEX.md Instantiate the BluetoothTransport class for Bluetooth connections. Provide the device's MAC address. ```python # Bluetooth from niimprint import BluetoothTransport transport = BluetoothTransport(address="E2:E1:08:03:09:87") ``` -------------------------------- ### Initialize SerialTransport Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/SerialTransport.md Initialize a serial transport connection. Use 'auto' for automatic detection, or specify a port path explicitly for Linux or Windows. ```python from niimprint import SerialTransport, PrinterClient # Auto-detect the serial port (only works if one port is available) transport = SerialTransport() printer = PrinterClient(transport) # Specify port explicitly on Linux transport = SerialTransport(port="/dev/ttyACM0") printer = PrinterClient(transport) # Specify port explicitly on Windows transport = SerialTransport(port="COM3") printer = PrinterClient(transport) ``` -------------------------------- ### Print Image via USB (Auto-detect Port) Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Connect to a printer using automatic USB port detection and print an image. Ensure 'label.png' is in the current directory. ```python from niimprint import SerialTransport, PrinterClient from PIL import Image # Connect to printer (auto-detects USB port) transport = SerialTransport() printer = PrinterClient(transport) # Load and print image image = Image.open("label.png") printer.print_image(image, density=4) print("Print complete!") ``` -------------------------------- ### Big-Endian 16-bit Integer Packing and Unpacking Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Demonstrates how to pack and unpack 16-bit integers using Python's struct module for big-endian byte representation. ```python import struct # Pack integer to big-endian bytes height = 120 data = struct.pack(">H", height) # Bytes: 0x00 0x78 # Unpack bytes to integer data = bytes([0x00, 0x78]) height = struct.unpack(">H", data)[0] # Value: 120 ``` -------------------------------- ### Convert Image to Grayscale Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md This Python snippet shows how to convert an image to grayscale using the Pillow library, which is often a required step before printing. ```python from PIL import Image image = Image.open("photo.png") image = image.convert("L") # Convert to grayscale image.save("label_grayscale.png") ``` -------------------------------- ### String Representation of NiimbotPacket Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/NiimbotPacket.md Demonstrates the __repr__ method for obtaining a developer-friendly string representation of a NiimbotPacket object. ```python from niimprint.packet import NiimbotPacket pkt = NiimbotPacket(0xDC, b"\x01") print(repr(pkt)) # ``` -------------------------------- ### Check niimprint Dependencies Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Verify that all necessary niimprint dependencies are successfully imported. This snippet ensures that the library and its core components are accessible. ```python import niimprint import serial from PIL import Image # All imports successful if no errors ``` -------------------------------- ### PrinterClient API Methods Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/README.md Overview of available methods for the PrinterClient class, including printing images, querying device information, and managing print sessions. ```python PrinterClient (main client) ├── print_image(image, density) Print with density control ├── get_info(key) Query device information ├── get_rfid() Read RFID label data ├── heartbeat() Check device status ├── set_label_density(n) Configure density ├── set_label_type(n) Set label type ├── start_print() Begin print session ├── end_print() Finalize and wait ├── start_page_print() Start page ├── end_page_print() End page ├── set_dimension(w, h) Set label size ├── set_quantity(n) Set copies ├── get_print_status() Query progress └── allow_print_clear() Clear buffer (optional) ``` -------------------------------- ### NiimbotPacket Constructor Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/NiimbotPacket.md Initializes a new Niimbot protocol packet with a specified type and data payload. The type is an integer code, and data is a byte string representing the packet's content. ```APIDOC ## NiimbotPacket Constructor ### NiimbotPacket(type_, data) Creates a new Niimbot protocol packet. #### Parameters - **type_** (int) - Required - Packet type code (0-255). Request codes defined in RequestCodeEnum. - **data** (bytes) - Required - Payload data for the packet. #### Example ```python from niimprint.packet import NiimbotPacket # Create a heartbeat packet pkt = NiimbotPacket(0xDC, b"\x01") # HEARTBEAT = 220 = 0xDC # Create a packet with structured data import struct dimension_data = struct.pack(">HH", 120, 240) # height=120, width=240 pkt = NiimbotPacket(0x13, dimension_data) # SET_DIMENSION = 19 = 0x13 ``` ``` -------------------------------- ### Create NiimbotPacket Instance Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/api-reference/NiimbotPacket.md Instantiate NiimbotPacket with a type code and payload data. Used for creating outgoing packets. ```python from niimprint.packet import NiimbotPacket # Create a heartbeat packet pkt = NiimbotPacket(0xDC, b"\x01") # HEARTBEAT = 220 = 0xDC # Create a packet with structured data import struct dimension_data = struct.pack(">HH", 120, 240) # height=120, width=240 pkt = NiimbotPacket(0x13, dimension_data) # SET_DIMENSION = 19 = 0x13 ``` -------------------------------- ### Analyzing Logged Packet Bytes Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/PROTOCOL_REFERENCE.md Demonstrates how to parse a logged packet's hex string into bytes and then into a NiimbotPacket object for analysis. ```python # Parse a logged packet hex_string = "55:55:01:01:01:xx:aa:aa" bytes_data = bytes.fromhex(hex_string.replace(":", "")) packet = NiimbotPacket.from_bytes(bytes_data) print(f"Type: {packet.type}, Data: {packet.data.hex()}") ``` -------------------------------- ### Initialize SerialTransport Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/INDEX.md Instantiate the SerialTransport class for USB/Serial connections. Optionally specify the port if auto-detection fails or is ambiguous. ```python # USB/Serial from niimprint import SerialTransport transport = SerialTransport(port="/dev/ttyACM0") ``` -------------------------------- ### Work with NiimbotPacket Directly Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md This Python snippet shows how to create, serialize, and deserialize NiimbotPacket objects, demonstrating direct packet manipulation. ```python from niimprint.packet import NiimbotPacket # Create packet pkt = NiimbotPacket(0x01, b"\x01") # START_PRINT # Serialize to bytes binary = pkt.to_bytes() print(f"Bytes: {binary.hex()}") # Deserialize from bytes pkt2 = NiimbotPacket.from_bytes(binary) print(f"Type: {pkt2.type}, Data: {pkt2.data.hex()}") ``` -------------------------------- ### PrinterClient Methods Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/INDEX.md The PrinterClient class provides the main interface for interacting with Niimbot printers. It exposes methods for printing images, retrieving device information, managing print jobs, and querying status. ```APIDOC ## PrinterClient ### Description Main printer client class for interacting with Niimbot printers. ### Methods - **`print_image(image, density)`**: Prints an image to the label. - **`get_info(key)`**: Retrieves specific information about the printer. - **`get_rfid()`**: Reads RFID tag data from the printer. - **`heartbeat()`**: Sends a heartbeat signal to the printer. - **`set_label_density(n)`**: Sets the label print density. - **`set_label_type(n)`**: Sets the label type. - **`start_print()`**: Initiates a print job. - **`end_print()`**: Ends the current print job. - **`start_page_print()`**: Starts printing a new page. - **`end_page_print()`**: Ends the current page printing. - **`set_dimension(w, h)`**: Sets the label dimensions (width and height). - **`set_quantity(n)`**: Sets the number of labels to print. - **`get_print_status()`**: Queries the current print status. - **`allow_print_clear()`**: Allows clearing the print buffer. ``` -------------------------------- ### Print on Specific Port via CLI Source: https://github.com/andbondstyle/niimprint/blob/main/_autodocs/QUICK_START.md Print an image file on a D11 printer using a specific USB port. ```bash python -m niimprint -m d11 -c usb -a /dev/ttyACM0 -i label.png ```