35
35
36
36
from micropython import const
37
37
38
+ try :
39
+ from typing import Optional , Type
40
+ from typing_extensions import Literal
41
+ from circuitpython_typing import ReadableBuffer
42
+ from busio import UART
43
+ except ImportError :
44
+ pass
38
45
39
46
__version__ = "0.0.0+auto.0"
40
47
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Thermal_Printer.git"
@@ -117,13 +124,17 @@ class _PrintModeBit:
117
124
# which by design only implements get, set, init. As a result workaround
118
125
# this pylint issue by disabling the warning.
119
126
# pylint: disable=too-few-public-methods
120
- def __init__ (self , mask ) :
127
+ def __init__ (self , mask : int ) -> None :
121
128
self ._mask = mask
122
129
123
- def __get__ (self , obj , objtype ):
130
+ def __get__ (
131
+ self ,
132
+ obj : Optional ["ThermalPrinter" ],
133
+ objtype : Type ["ThermalPrinter" ],
134
+ ) -> bool :
124
135
return obj ._print_mode & self ._mask > 0
125
136
126
- def __set__ (self , obj , val ) :
137
+ def __set__ (self , obj : "ThermalPrinter" , val : int ) -> None :
127
138
if val :
128
139
obj ._set_print_mode (self ._mask )
129
140
else :
@@ -134,13 +145,13 @@ def __set__(self, obj, val):
134
145
135
146
def __init__ (
136
147
self ,
137
- uart ,
148
+ uart : UART ,
138
149
* ,
139
- byte_delay_s = 0.00057346 ,
140
- dot_feed_s = 0.0021 ,
141
- dot_print_s = 0.03 ,
142
- auto_warm_up = True
143
- ):
150
+ byte_delay_s : float = 0.00057346 ,
151
+ dot_feed_s : float = 0.0021 ,
152
+ dot_print_s : float = 0.03 ,
153
+ auto_warm_up : bool = True ,
154
+ ) -> None :
144
155
"""Thermal printer class. Requires a serial UART connection with at
145
156
least the TX pin connected. Take care connecting RX as the printer
146
157
will output a 5V signal which can damage boards! If RX is unconnected
@@ -176,16 +187,16 @@ def __init__(
176
187
if auto_warm_up :
177
188
self .warm_up ()
178
189
179
- def _set_timeout (self , period_s ) :
190
+ def _set_timeout (self , period_s : float ) -> None :
180
191
# Set a timeout before future commands can be sent.
181
192
self ._resume = time .monotonic () + period_s
182
193
183
- def _wait_timeout (self ):
194
+ def _wait_timeout (self ) -> None :
184
195
# Ensure the timeout that was previously set has passed (will busy wait).
185
196
while time .monotonic () < self ._resume :
186
197
pass
187
198
188
- def _write_char (self , char ) :
199
+ def _write_char (self , char : str ) -> None :
189
200
# Write a single character to the printer.
190
201
if char == "\r " :
191
202
return # Strip carriage returns by skipping them.
@@ -207,33 +218,33 @@ def _write_char(self, char):
207
218
self ._column += 1
208
219
self ._set_timeout (delay )
209
220
210
- def _write_print_mode (self ):
221
+ def _write_print_mode (self ) -> None :
211
222
# Write the printer mode to the printer.
212
223
self .send_command (
213
- "\x1B !{0}" . format ( chr (self ._print_mode ))
224
+ f "\x1B !{ chr (self ._print_mode )} "
214
225
) # ESC + '!' + print mode byte
215
226
# Adjust character height and column count based on print mode.
216
227
self ._char_height = 48 if self ._print_mode & _DOUBLE_HEIGHT_MASK else 24
217
228
self ._max_column = 16 if self ._print_mode & _DOUBLE_WIDTH_MASK else 32
218
229
219
- def _set_print_mode (self , mask ) :
230
+ def _set_print_mode (self , mask : int ) -> None :
220
231
# Enable the specified bits of the print mode.
221
232
self ._print_mode |= mask & 0xFF
222
233
self ._write_print_mode ()
223
234
224
- def _unset_print_mode (self , mask ) :
235
+ def _unset_print_mode (self , mask : int ) -> None :
225
236
# Disable the specified bits of the print mode.
226
237
self ._print_mode &= ~ (mask & 0xFF )
227
238
self ._write_print_mode ()
228
239
229
- def send_command (self , command ) :
240
+ def send_command (self , command : str ) -> None :
230
241
"""Send a command string to the printer."""
231
242
self ._uart .write (bytes (command , "ascii" ))
232
243
233
244
# Do initialization in warm_up instead of the initializer because this
234
245
# initialization takes a long time (5 seconds) and shouldn't happen during
235
246
# object creation (users need explicit control of when to start it).
236
- def warm_up (self , heat_time = 120 ):
247
+ def warm_up (self , heat_time : int = 120 ) -> None :
237
248
"""Initialize the printer. Can specify an optional heat_time keyword
238
249
to override the default heating timing of 1.2 ms. See the datasheet
239
250
for details on the heating time value (duration in 10uS increments).
@@ -261,7 +272,7 @@ def warm_up(self, heat_time=120):
261
272
# possibly paper 'stiction'. More heating interval = clearer print,
262
273
# but slower printing speed.
263
274
# Send ESC + '7' (print settings) + heating dots, heat time, heat interval.
264
- self .send_command ("\x1B 7\x0B {0} \x28 " . format ( chr (heat_time )) )
275
+ self .send_command (f "\x1B 7\x0B { chr (heat_time )} \x28 " )
265
276
# Print density description from manual:
266
277
# DC2 # n Set printing density
267
278
# D4..D0 of n is used to set the printing density. Density is
@@ -271,9 +282,9 @@ def warm_up(self, heat_time=120):
271
282
print_density = 10 # 100% (? can go higher, text is darker but fuzzy)
272
283
print_break_time = 2 # 500 uS
273
284
dc2_value = (print_break_time << 5 ) | print_density
274
- self .send_command ("\x12 #{0}" . format ( chr (dc2_value )) ) # DC2 + '#' + value
285
+ self .send_command (f "\x12 #{ chr (dc2_value )} " ) # DC2 + '#' + value
275
286
276
- def reset (self ):
287
+ def reset (self ) -> None :
277
288
"""Reset the printer."""
278
289
# Issue a reset command to the printer. (ESC + @)
279
290
self .send_command ("\x1B @" )
@@ -287,7 +298,7 @@ def reset(self):
287
298
# ESC + 'D' + tab stop value list ending with null to terminate.
288
299
self .send_command ("\x1B D\x04 \x08 \x10 \x14 \x18 \x1C \x00 " )
289
300
290
- def print (self , text , end = "\n " ):
301
+ def print (self , text : str , end : Optional [ str ] = "\n " ) -> None :
291
302
"""Print a line of text. Optionally specify the end keyword to
292
303
override the new line printed after the text (set to None to disable
293
304
the new line entirely).
@@ -297,7 +308,7 @@ def print(self, text, end="\n"):
297
308
if end is not None :
298
309
self ._write_char (end )
299
310
300
- def print_barcode (self , text , barcode_type ) :
311
+ def print_barcode (self , text : str , barcode_type : int ) -> None :
301
312
"""Print a barcode with the specified text/number (the meaning
302
313
varies based on the type of barcode) and type. Type is a value from
303
314
the datasheet or class-level variables like UPC_A, etc. for
@@ -309,14 +320,14 @@ def print_barcode(self, text, barcode_type):
309
320
self .feed (1 ) # Recent firmware can't print barcode w/o feed first???
310
321
self .send_command ("\x1D H\x02 " ) # Print label below barcode
311
322
self .send_command ("\x1D w\x03 " ) # Barcode width 3 (0.375/1.0mm thin/thick)
312
- self .send_command ("\x1D k{0}" . format ( chr (barcode_type )) ) # Barcode type
323
+ self .send_command (f "\x1D k{ chr (barcode_type )} " ) # Barcode type
313
324
# Write length and then string (note this only works with 2.64+).
314
325
self .send_command (chr (len (text )))
315
326
self .send_command (text )
316
327
self ._set_timeout ((self ._barcode_height + 40 ) * self ._dot_print_s )
317
328
self ._column = 0
318
329
319
- def _print_bitmap (self , width , height , data ) :
330
+ def _print_bitmap (self , width : int , height : int , data : ReadableBuffer ) -> None :
320
331
"""Print a bitmap image of the specified width, height and data bytes.
321
332
Data bytes must be in 1-bit per pixel format, i.e. each byte represents
322
333
8 pixels of image data along a row of the image. You will want to
@@ -338,9 +349,7 @@ def _print_bitmap(self, width, height, data):
338
349
for row_start in range (0 , height , chunk_height_limit ):
339
350
# Issue up to chunkHeightLimit rows at a time.
340
351
chunk_height = min (height - row_start , chunk_height_limit )
341
- self .send_command (
342
- "\x12 *{0}{1}" .format (chr (chunk_height ), chr (row_bytes_clipped ))
343
- )
352
+ self .send_command (f"\x12 *{ chr (chunk_height )} { chr (row_bytes_clipped )} " )
344
353
for _ in range (chunk_height ):
345
354
for _ in range (row_bytes_clipped ):
346
355
# Drop down to low level UART access to avoid newline and
@@ -352,7 +361,7 @@ def _print_bitmap(self, width, height, data):
352
361
self ._set_timeout (chunk_height * self ._dot_print_s )
353
362
self ._column = 0
354
363
355
- def test_page (self ):
364
+ def test_page (self ) -> None :
356
365
"""Print a test page."""
357
366
self .send_command ("\x12 T" ) # DC2 + 'T' for test page
358
367
# Delay for 26 lines w/text (ea. 24 dots high) +
@@ -361,7 +370,7 @@ def test_page(self):
361
370
self ._dot_print_s * 24 * 26 + self ._dot_feed_s * (6 * 26 + 30 )
362
371
)
363
372
364
- def set_defaults (self ):
373
+ def set_defaults (self ) -> None :
365
374
"""Set default printing and text options. This is useful to reset back
366
375
to a good state after printing different size, weight, etc. text.
367
376
"""
@@ -383,7 +392,7 @@ def set_defaults(self):
383
392
self ._set_charset ()
384
393
self ._set_code_page ()
385
394
386
- def _set_justify (self , val ) :
395
+ def _set_justify (self , val : Literal [ 0 , 1 , 2 ]) -> None :
387
396
assert 0 <= val <= 2
388
397
if val == JUSTIFY_LEFT :
389
398
self .send_command ("\x1B a\x00 " ) # ESC + 'a' + 0
@@ -404,7 +413,7 @@ def _set_justify(self, val):
404
413
)
405
414
# pylint: enable=line-too-long
406
415
407
- def _set_size (self , val ) :
416
+ def _set_size (self , val : Literal [ 0 , 1 , 2 ]) -> None :
408
417
assert 0 <= val <= 2
409
418
if val == SIZE_SMALL :
410
419
self ._char_height = 24
@@ -432,7 +441,7 @@ def _set_size(self, val):
432
441
)
433
442
# pylint: enable=line-too-long
434
443
435
- def _set_underline (self , val ) :
444
+ def _set_underline (self , val : Optional [ Literal [ 0 , 1 ]]) -> None :
436
445
assert val is None or (0 <= val <= 1 )
437
446
if val is None :
438
447
# Turn off underline.
@@ -454,7 +463,7 @@ def _set_underline(self, val):
454
463
)
455
464
# pylint: enable=line-too-long
456
465
457
- def _set_inverse (self , inverse ) :
466
+ def _set_inverse (self , inverse : bool ) -> None :
458
467
# Set the inverse printing state to enabled disabled with the specified
459
468
# boolean value. This requires printer firmare 2.68+
460
469
if inverse :
@@ -474,7 +483,7 @@ def _set_inverse(self, inverse):
474
483
)
475
484
# pylint: enable=line-too-long
476
485
477
- def _set_up_down_mode (self , up_down_mode ) :
486
+ def _set_up_down_mode (self , up_down_mode : bool ) -> None :
478
487
if up_down_mode :
479
488
self .send_command ("\x1B {\x01 " )
480
489
@@ -496,35 +505,35 @@ def _set_up_down_mode(self, up_down_mode):
496
505
497
506
bold = _PrintModeBit (_BOLD_MASK )
498
507
499
- def feed (self , lines ) :
508
+ def feed (self , lines : int ) -> None :
500
509
"""Advance paper by specified number of blank lines."""
501
510
assert 0 <= lines <= 255
502
- self .send_command ("\x1B d{0}" . format ( chr (lines )) )
511
+ self .send_command (f "\x1B d{ chr (lines )} " )
503
512
self ._set_timeout (self ._dot_feed_s * self ._char_height )
504
513
self ._column = 0
505
514
506
- def feed_rows (self , rows ) :
515
+ def feed_rows (self , rows : int ) -> None :
507
516
"""Advance paper by specified number of pixel rows."""
508
517
assert 0 <= rows <= 255
509
- self .send_command ("\x1B J{0}" . format ( chr (rows )) )
518
+ self .send_command (f "\x1B J{ chr (rows )} " )
510
519
self ._set_timeout (rows * self ._dot_feed_s )
511
520
self ._column = 0
512
521
513
- def flush (self ):
522
+ def flush (self ) -> None :
514
523
"""Flush data pending in the printer."""
515
524
self .send_command ("\f " )
516
525
517
- def offline (self ):
526
+ def offline (self ) -> None :
518
527
"""Put the printer into an offline state. No other commands can be
519
528
sent until an online call is made.
520
529
"""
521
530
self .send_command ("\x1B =\x00 " ) # ESC + '=' + 0
522
531
523
- def online (self ):
532
+ def online (self ) -> None :
524
533
"""Put the printer into an online state after previously put offline."""
525
534
self .send_command ("\x1B =\x01 " ) # ESC + '=' + 1
526
535
527
- def has_paper (self ):
536
+ def has_paper (self ) -> bool :
528
537
"""Return a boolean indicating if the printer has paper. You MUST have
529
538
the serial RX line hooked up for this to work. NOTE: be VERY CAREFUL
530
539
to ensure your board can handle a 5V serial input before hooking up
@@ -537,38 +546,38 @@ def has_paper(self):
537
546
return False
538
547
return not status [0 ] & 0b00000100
539
548
540
- def _set_line_height (self , height ) :
549
+ def _set_line_height (self , height : int ) -> None :
541
550
"""Set the line height in pixels. This is the total amount of space
542
551
between lines, including the height of text. The smallest value is 24
543
552
and the largest is 255.
544
553
"""
545
554
assert 24 <= height <= 255
546
555
self ._line_spacing = height - 24
547
- self .send_command ("\x1B 3{0}" . format ( chr (height )) ) # ESC + '3' + height
556
+ self .send_command (f "\x1B 3{ chr (height )} " ) # ESC + '3' + height
548
557
549
- def _set_barcode_height (self , height ) :
558
+ def _set_barcode_height (self , height : int ) -> None :
550
559
"""Set the barcode height in pixels. Must be a value 1 - 255."""
551
560
assert 1 <= height <= 255
552
561
self ._barcode_height = height
553
- self .send_command ("\x1D h{0}" . format ( chr (height )) ) # ASCII GS + 'h' + height
562
+ self .send_command (f "\x1D h{ chr (height )} " ) # ASCII GS + 'h' + height
554
563
555
- def _set_charset (self , charset = 0 ) :
564
+ def _set_charset (self , charset : int = 0 ) -> None :
556
565
"""Alters the character set for ASCII characters 0x23-0x7E. See
557
566
datasheet for details on character set values (0-15). Note this is only
558
567
supported on more recent firmware printers!
559
568
"""
560
569
assert 0 <= charset <= 15
561
- self .send_command ("\x1B R{0}" . format ( chr (charset )) ) # ESC + 'R' + charset
570
+ self .send_command (f "\x1B R{ chr (charset )} " ) # ESC + 'R' + charset
562
571
563
- def _set_code_page (self , code_page = 0 ) :
572
+ def _set_code_page (self , code_page : int = 0 ) -> None :
564
573
"""Select alternate code page for upper ASCII symbols 0x80-0xFF. See
565
574
datasheet for code page values (0 - 47). Note this is only supported
566
575
on more recent firmware printers!
567
576
"""
568
577
assert 0 <= code_page <= 47
569
- self .send_command ("\x1B t{0}" . format ( chr (code_page )) ) # ESC + 't' + code page
578
+ self .send_command (f "\x1B t{ chr (code_page )} " ) # ESC + 't' + code page
570
579
571
- def tab (self ):
580
+ def tab (self ) -> None :
572
581
"""Print a tab (i.e. move to next 4 character block). Note this is
573
582
only supported on more recent firmware printers!"""
574
583
self .send_command ("\t " )
0 commit comments