Skip to content

Commit

Permalink
Merge pull request #13 from bitrate16/refactor-to-peripage
Browse files Browse the repository at this point in the history
Refactor to peripage
  • Loading branch information
bitrate16 authored May 7, 2023
2 parents c9cf0ac + 8433911 commit b2d2a9b
Show file tree
Hide file tree
Showing 18 changed files with 2,111 additions and 1,433 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*__pycache__*
155 changes: 90 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
# ppa6-python
### Python module for printing on Peripage A6 and A6+
# peripage-python
### Python module for printing on Peripage printers

**This project is a continued development of the [original project](https://github.com/eliasweingaertner/peripage-A6-bluetooth) made by [Elias Weingärtner](https://github.com/eliasweingaertner). This module combined all results of reverse engineering of the Peripage A6/A6+ protocol in a python utility providing interface and CLI tool for printing on this thermal printer.**

## [The original introduction](https://github.com/eliasweingaertner/peripage-A6-bluetooth#introduction)

The Peripage A6 F622 is an inexpensive portable thermal printer. It provides both Bluetooth and USB connectivity. Unlike most other thermo printers it **does not** seem to support ESC/POS or any other standardized printer control language.
The Peripage A6 F622 is an inexpensive portable thermal printer. It provides both Bluetooth and USB connectivity. Unlike most other thermo printers it **does not** seem to support ESC/POS or any other standardized printer control language.

So far, the Peripage A6 F622 can be only controlled using a proprietary app (iOS / Anndroid). There is also a driver for Windows with many limitations, most notably the need of defining a page size before printing; this is a huge limitation, as the Peripage prints on continuous form paper.

The script provided here was built based on an analysis of captured Bluetooth traffic between the printer and an Android device. The Peripage A6 uses the serial profile (BTSPP) and RFCOMM.
The script provided here was built based on an analysis of captured Bluetooth traffic between the printer and an Android device. The Peripage A6 uses the serial profile (BTSPP) and RFCOMM.

Essentially, the script takes an input images, scales it to the printers native X resolution of 384 pixels, and then sends it to the printer.

## Current abilities
## Deprecation Warning

**The latest version ot `ppa6-python` module is deprecated due the major update with new models support and better module naming**

## Features

* Printing text of any length encoded in ASCII
* Printing Images using PIL library
* Printing raw bytes representing image in binary (black/white) form
* Printing a page break of desired size (in pixels)
* Printing using generator/iterator which returns image row by row in form of bytes or PIL Images
* Printing Images row-by row using binary row representation
* Printing page breaks using paper feed
* Printing using generator/iterator that return bytes for each row, chunks of bytes for each row, images
* Requesting printer details (Serial Number, Name, Battery Level, Hardware Info and an option the meaning of which i don't know)
* Configuring print concentration (light, gray, black)
* Configuring print concentration (temperature)
* Changing printer serial number
* Configuring printer poweroff timeout
* Supported printers:
* Peripage A6
* Peripage A6+
* Peripage A40

## Prerequisites

## Prerequirements
* Peripage A6/A6+ printer
* Peripage A6/A6+/A40/e.t.c printer
* Python 3

## Installation
Expand All @@ -40,35 +50,18 @@ pip install . --user
**Install from pypi using pip**

```
pip install ppa6
pip install peripage
```

## Dependencies
* `PyBluez==0.30`
* `Pillow==8.1.2`
* `argparse==1.1` (for CLI)

* `PyBluez>=0.30`
* `Pillow>=8.1.2`
* `argparse>=1.1`

Install dependencies with
`pip install -r requirements.txt`

On windows you may need to install PyBluez 0.3
```
git clone https://github.com/pybluez/pybluez
cd pybluez
pip install . --user
```

On raspberry pi it may require to install additional libraries
```
sudo apt install libbluetooth-dev libopenjp2-7 libtiff5
```

And in some cases you will have to restart the bluetooth adapter and service on raspberry pi when it fails to connect or device is busy
```
sudo systemctl restart bluetooth
sudo hciconfig hci0 reset
```

## Identify printer Bluetooth MAC address

**On linux:**
Expand Down Expand Up @@ -100,68 +93,84 @@ Scanning bluetooth devices... please wait.
00:15:83:15:bc:5f Imaging PeriPage+BC5F
```

## Troubleshooting

> Windows installation requires installing PyBluez from master branch as pypi module is not updated
```
pip install git+https://github.com/pybluez/pybluez@master#egg=pybluez --user
```

> Raspberry PI installation requires additional libraries
```
sudo apt install libbluetooth-dev libopenjp2-7 libtiff5
```

> Some cases may require restarting bluetooth adapter
```
sudo systemctl restart bluetooth
sudo hciconfig hci0 reset
```

## CLI usage

**On linux**

Install module and run
`ppa6 <args>`
`peripage <args>`

**On windows**

Install module and run
`python -m ppa6 <args>`
`python -m peripage <args>`

### Options

```
usage: ppa6 [-h] -m MAC [-c [0-2]] [-b [0-255]] [-p {A6,A6p,A6+}] [-n]
(-t TEXT | -s | -i IMAGE | -q QR | -e)
$ python -m peripage -h
usage: __main__.py [-h] -m MAC [-c [0-2]] [-b [0-255]] -p {A6,A6p,A40} (-t TEXT | -s | -i IMAGE | -q QR | -e)
Print on a Peripage A6 / A6+ via bluetooth
Print on a Peripage printer via bluetooth
optional arguments:
-h, --help show this help message and exit
-m MAC, --mac MAC Bluetooth MAC address of the printer
-c [0-2], --concentration [0-2]
Concentration value for printing (0, 1, 2)
Concentration value for printing (temperature)
-b [0-255], --break [0-255]
Size of the break that should be inserted after the
print (max 255)
-p {A6,A6p,A6+}, --printer {A6,A6p,A6+}
Printer model name (A6 or A6+/A6p (both allowed))
-n, --newline Force printer to add newline at the end of the printed
text and flush the buffer
-t TEXT, --text TEXT ASCII text that should be printed. Add a line break at
the end of the string to avoid it being cut. String
can be empty, so just page break will be printed
-s, --stream Reads an input from stdin and prints as ASCII text
Size of the break inserted after printed image or text
-p {A6,A6p,A40}, --printer {A6,A6p,A40}
Printer model selection
-t TEXT, --text TEXT ASCII text to print. Text must be ASCII-safe and will be filtered for invalid characters
-s, --stream Print text received from STDIN, line by line. Text must be ASCII-safe and will be filtered for invalid characters
-i IMAGE, --image IMAGE
Path to the image that should be printed
-q QR, --qr QR String for QR code print
-e, --introduce Ask the printer to introduce himself
Path to the image for printing
-q QR, --qr QR String to convert into a QR code for printing
-e, --introduce Ask the printer to introduce itself
```

### Print image example

**Print image from [file](https://github.com/bitrate16/ppa6-python/blob/main/honk.png) with following break for 100px and concentration set to 2 (HIGH) on A6+**
**Print image from [file](https://github.com/bitrate16/peripage-python/blob/main/honk.png) with following break for 100px and concentration set to 2 (HIGH) on A6+**
```
ppa6 -m 00:15:83:15:bc:5f -p A6p -b 100 -c 2 -i honk.png
peripage -m 00:15:83:15:bc:5f -p A6p -b 100 -c 2 -i honk.png
```

### Print text example

**Print some random text followed by newline and break for 100px on A6+**
```
ppa6 -m 00:15:83:15:bc:5f -p A6p -b 100 -t "HONK" -n
peripage -m 00:15:83:15:bc:5f -p A6p -b 100 -t "HONK" -n
```
Newline is required to fush the internal printer buffer and force it to print all text without cutting

### Print Service example
## Print Service

**Print 50 text tasks on A6+**
```python
import ppa6
import peripage
import print_service

# Ping battery every 60 seconds
Expand All @@ -170,13 +179,14 @@ import print_service
# Wait 1 second before send after connecting/reconnecting to printer
# Print only after pinging printer and waiting for 1 second
service = print_service.PrintService(60, 5, 5, 1, 1)
service.start('00:15:83:15:bc:5f', ppa6.PrinterType.A6p)
service.start('00:15:83:15:bc:5f', peripage.PrinterType.A6p)
for i in range(50):
service.add_print_ascii(f'number {i}', flush=True)
```
Newline is required to fush the internal printer buffer and force it to print all text without cutting

### Suggestions
## Recommendations

* Don't forget about concentration, this can make print brighter and better visible.
* Split long images into multiple print requests with cooldown time for printer (printer may overheat during a long print and will stop printing for a while. This will result in partial print loss because the internal buffer is about 250px height). For example, when you print [looooooooooooooooooooooooooooooongcat.jpg](http://lurkmore.so/images/9/91/Loooooooooooooooooooooooooooooooooooooooooongcat.JPG), split it into at least 20 pieces with 1-2 minutes delay because you will definetly loose something without cooling. Printer gets hot very fast. Yes, it was the first that i've printed.
* Be carefull when printing lots of black or using max concentration, as i said, printer heats up very fast.
Expand All @@ -186,7 +196,9 @@ Newline is required to fush the internal printer buffer and force it to print al

## Code example

View this [python notebook](https://github.com/bitrate16/ppa6-python/blob/main/notebooks/ppa6-tutorial.ipynb) for tutorial
View this [python notebook](https://github.com/bitrate16/peripage-python/blob/main/notebooks/peripage-tutorial.ipynb) for tutorial

View this [python notebook](https://github.com/bitrate16/peripage-python/blob/main/notebooks/Test-notebook.ipynb) for test

## Printer disassembly

Expand All @@ -196,20 +208,33 @@ View this [python notebook](https://github.com/bitrate16/ppa6-python/blob/main/n

* Fix page sometimes get cutted off for some rows
* Fix delays
* Python 2.7 support
* ~~Python 2.7 support~~ (Don't need)
* Implement overheat protection
* Implement cover open handler
* Tweak wait timings to precisely match the printing speed
* Tweak wait timings to precisely match printing speed
* Implement printer renaming
* Implement printing stop operation
* Reverse-engineer USB driver and add support for it
* **FIX:** Print randomly gets cropped (some images getting cropped)
* **FIX:** 1 type conversion is low quality
* Print randomly gets cropped (some images getting cropped)
* 1 type conversion is low quality

## Contribution

> Q: How to contribute?
>
> A: Implement some features and make a pull request in this repo. For example, you could add info about USB communication, write a any-font printing using PIL text drawing, make an additional research in protocol and other cool things.
> Q: How to get my printer supported?
>
> A: If you own a peripage printer that is currently unsupported, you can reverse-engineer the bluetooth packets captured from the oficial printing app and find out the specs of your printer (the main and the only spec is bytes per row). Another way is to find how many letters can fit in a row when using `printASCII()`.
>
> If you would like to participate, please make an issue and I will guide you on how to obtain required parameters.
## Credits

* [Elias Weingärtner](https://github.com/eliasweingaertner) for initial work in reverse-engineering bluetooth protocol
* [bitrate16](https://github.com/bitrate16) for additional research and python module
* [henryleonard](https://github.com/henryleonard) for specs of A40 printer

## Disclaimer

Expand All @@ -223,4 +248,4 @@ SOFTWARE.**

## License

[MIT License](https://github.com/bitrate16/ppa6-python/blob/main/LICENSE)
[MIT License](https://github.com/bitrate16/peripage-python/blob/main/LICENSE)
Loading

0 comments on commit b2d2a9b

Please sign in to comment.