class TSC_Label
A class for creating and printing TSCPL2 format labels for laboratory information system (LIS) objects, specifically designed for TSC label printers with support for DataMatrix barcodes and text formatting.
/tf/active/vicechatdev/resources/printers.py
639 - 724
complex
Purpose
TSC_Label manages the creation and printing of TSCPL2-formatted labels for laboratory slides and other LIS objects. It interfaces with a Neo4j graph database to retrieve object information, generates TSCPL2 printer commands including DataMatrix barcodes and formatted text, and sends print jobs to a TSC label printer via CUPS. The class handles printer queue setup, label formatting with study/customer information, and temporary file management for print operations.
Source Code
class TSC_Label:
'''
Used to build a TSCPL2 label.
'''
def __init__(self, height=18.0, width=22.0, dpmm=8.0,server="10.200.200.12",queue="TSC_slidelabel"):
"""
Creates one (or more) TSCPL2 labels.
*height* and *width* are given in millimeters
*dpmm* refers to dots per millimeter (e.g. 12 for 300dpi)
"""
self.height = height
self.width = width
self.dpmm = dpmm
self.code = "SIZE "+str(int(width))+"mm,"+str(int(height))+"mm \n DIRECTION 1 \n CLS \n"
self.graph = Graph(config.DB_ADDR, auth=config.DB_AUTH, name=config.DB_NAME)
self.server=server
self.queue=queue
self.setup_queue()
return
def setup_queue(self):
if not os.path.exists('/etc/cups'):
os.mkdir('/etc/cups')
# This is the VPN IP address of the local print server
try:
os.remove("/etc/cups/client.conf")
except:
pass
os.system("echo 'ServerName "+self.server+"' > /etc/cups/client.conf")
return
def print_lis_label(self,lis_obj_uid):
def print_slide(print_obj):
name=print_obj['N']
obj_type=list(print_obj._labels)[0]
today = dt.datetime.now().strftime('%Y-%m-%d')
study = self.graph.run("MATCH (s:Slide {UID:'"+print_obj['UID']+"'})<-[*]-(b:Study) RETURN b.N").evaluate()
today = dt.datetime.now().strftime('%Y-%m-%d')
customer=self.graph.run(f"""MATCH (s:Slide {{UID:'{print_obj['UID']}'}})<-[*]-(c:Customer)
RETURN DISTINCT CASE WHEN c.shorthand IS NOT NULL THEN c.shorthand ELSE c.N END""").evaluate()
if customer==None:
customer = "internal"
staining=print_obj['T']
self.code=self.code+'DMATRIX 10,20,80,80,"'+str(name)+'" \n'
self.code=self.code+'TEXT 5,90, "0",0,8,8,0, "'+str(name)+'" \n'
self.code=self.code+'TEXT 80,10, "0",0,6,6,0, "'+today+'" \n'
self.code=self.code+'TEXT 80,40, "0",0,8,8,0, "'+staining+'" \n'
self.code=self.code+'TEXT 5,120, "0",0,6,6,0, "'+str(customer)+'/'+str(study)+'" \n'
self._print()
return
def print_other(print_obj):
pass
g_text="match (o {UID:'"+lis_obj_uid+"'}) return o"
print_objs=self.graph.run(g_text).to_subgraph()
print(f"UID is {lis_obj_uid}, print objects = {print_objs}")
if print_objs != None:
print_obj=list(print_objs.nodes)[0]
obj_type=list(print_obj._labels)[0]
switcher = {
'Slide':print_slide
}
func = switcher.get(obj_type, print_other)
return func(print_obj)
def _print(self):
if not os.path.exists(os.path.join(os.path.abspath('.'),'temp')):
os.mkdir(os.path.join(os.path.abspath('.'),'temp'))
temp_file=os.path.join(os.path.abspath('.'),'temp','label_out.zpl')
with open(temp_file, 'w') as f:
f.write(self.code+' PRINT 1 \n')
if config.PRINT_TSC:
os.system('lp -d '+self.queue+' -o raw '+temp_file)
else:
print('lp -d '+self.queue+' -o raw '+self.code)
os.remove(temp_file)
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
bases |
- | - |
Parameter Details
height: Height of the label in millimeters. Default is 18.0mm. This determines the vertical size of the printed label.
width: Width of the label in millimeters. Default is 22.0mm. This determines the horizontal size of the printed label.
dpmm: Dots per millimeter resolution for the printer. Default is 8.0 (approximately 203 DPI). Higher values like 12 correspond to 300 DPI for finer print quality.
server: IP address or hostname of the CUPS print server. Default is '10.200.200.12'. This is typically the VPN IP address of the local print server.
queue: Name of the printer queue in CUPS. Default is 'TSC_slidelabel'. This identifies which printer to send jobs to.
Return Value
The __init__ method returns None (implicitly). The print_lis_label method returns the result of the internal print function (print_slide or print_other) which also returns None. The _print method returns None after sending the print job.
Class Interface
Methods
__init__(self, height=18.0, width=22.0, dpmm=8.0, server='10.200.200.12', queue='TSC_slidelabel') -> None
Purpose: Initializes a TSC_Label instance with label dimensions, printer resolution, and print server configuration. Sets up the CUPS client configuration and establishes Neo4j database connection.
Parameters:
height: Label height in millimeters (default 18.0)width: Label width in millimeters (default 22.0)dpmm: Dots per millimeter resolution (default 8.0)server: CUPS print server IP address (default '10.200.200.12')queue: CUPS printer queue name (default 'TSC_slidelabel')
Returns: None
setup_queue(self) -> None
Purpose: Configures the CUPS client by creating /etc/cups directory if needed and writing the print server address to client.conf. This method is called automatically during initialization.
Returns: None
print_lis_label(self, lis_obj_uid: str) -> None
Purpose: Queries the Neo4j database for an LIS object by UID, generates appropriate TSCPL2 label code based on object type (Slide or other), and sends the print job. Handles different object types through internal dispatcher functions.
Parameters:
lis_obj_uid: Unique identifier (UID) of the LIS object (e.g., Slide) to print a label for
Returns: None (returns the result of the internal print function)
_print(self) -> None
Purpose: Internal method that writes the accumulated TSCPL2 code to a temporary file and sends it to the printer via CUPS lp command. Creates temp directory if needed and cleans up the temporary file after printing.
Returns: None
Attributes
| Name | Type | Description | Scope |
|---|---|---|---|
height |
float | Label height in millimeters | instance |
width |
float | Label width in millimeters | instance |
dpmm |
float | Printer resolution in dots per millimeter | instance |
code |
str | Accumulated TSCPL2 printer command code string, initialized with SIZE, DIRECTION, and CLS commands | instance |
graph |
Graph | Neo4j graph database connection object for querying LIS data | instance |
server |
str | IP address or hostname of the CUPS print server | instance |
queue |
str | Name of the CUPS printer queue to send print jobs to | instance |
Dependencies
neo4j_driverosPILdatetimemathrepylibdmtxnumpyconfig
Required Imports
from neo4j_driver import *
import os
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from PIL import ImageOps
import datetime as dt
import math
import re
from pylibdmtx.pylibdmtx import decode
from pylibdmtx.pylibdmtx import encode
import numpy as np
import config
Usage Example
# Initialize the label printer
label_printer = TSC_Label(height=18.0, width=22.0, dpmm=8.0, server='10.200.200.12', queue='TSC_slidelabel')
# Print a label for a slide with a specific UID
slide_uid = 'SLIDE-12345-ABC'
label_printer.print_lis_label(slide_uid)
# The class will:
# 1. Query the Neo4j database for the slide information
# 2. Generate TSCPL2 code with DataMatrix barcode and text
# 3. Create a temporary file with the print commands
# 4. Send the job to the CUPS printer queue
# 5. Clean up the temporary file
Best Practices
- Ensure Neo4j database connection is properly configured in config module before instantiation
- Verify CUPS is installed and the print server is accessible before creating instances
- The class modifies /etc/cups/client.conf on instantiation, requiring appropriate permissions
- Set config.PRINT_TSC to False during testing to avoid actual print jobs
- The class creates a ./temp directory if it doesn't exist; ensure write permissions in the working directory
- Each call to print_lis_label queries the database, so ensure the UID exists before calling
- The class is designed for Slide objects primarily; other object types will use the print_other function which is currently a no-op
- Temporary files are automatically cleaned up after printing, but ensure the temp directory is periodically maintained
- The TSCPL2 code is built incrementally in the self.code attribute and reset on each print operation
- Network connectivity to both the Neo4j database and print server is required for full functionality
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
class print_client 65.5% similar
-
class NodeLabels_v1 51.2% similar
-
class NodeLabels 51.1% similar
-
class Cassette_Printer 50.3% similar
-
function main_v117 45.9% similar