Using a POS Printer to get my day organized
18.10.2022A while ago I got my fingers onto an old but perfectly functional thermal receipt printer. I took it back home because back then I had the idea to develop a POS software for the bar I used to co-administer for one semester during university. Currently, I am still working on this project, but it will take some time until the system is usable behind the bar counter.
While I had this printer laying on my desk and occupying space I thought, maybe I could use this printer to print more than just receipts, so the idea developed to use this machine to print a daily status excerpt. The excerpt should contain the weather report, my appointment, my todos, and the current headlines.
But let's start first, how are we able to print on this thing? On a "normal" inkjet or laser printer you would just plug a USB cord from your PC directly into the printer, install the driver delivered by the vendor, and you're ready to print from every application that supports printing via the OSes inbuilt printing system, like CUPS.
Thermal receipt printers, also called POS printers for Point-of-sale, are very limited from a graphical perspective. They are optimized for printing black-and-White text or barcodes very fast and maybe a header image, but not for drawing complex shapes. So because of that, they don't quite fit in the OSes inbuilt printing system. Although there are still drivers for doing this, that is rendering the page into a raster image and handing this off to the POS printer. But this is rather slow and the print quality isn't great if the printing application isn't especially developed to support this kind of printer.
Introduction to ESC/POS
Most of the POS printers available on the market use the ESC/POS command set for accepting print jobs Although initially developed by EPSON pretty much every POS printer supports the ESC/POS command set. Serialized commands are transferred over USB, Bluetooth, WLAN, or just a serial connection to the printer.
The following is an example of an ESC/POS command stream.
ESC and GS denote the beginning of a command, they are encoded as 0x1b
and 0x1d
respectively.
ESC a 0x01 # Align: Center
Hello # Print "Hello" centered
LF # New Line
ESC E 0x01 # Emphasized/Bold: true
World # Print "World" centered and bold
LF # New Line
ESC E 0x00 # Emphasized/Bold: false
GS k 0x03 12345678 0x00 # Print EAN8 Barcode "12345678"
GS V 0x00 # Full cut paper
Describing printouts directly in the serialized form can be quite tedious, so I decided to rely on a library instead that abstracts the commands a bit. As I wanted to proceed in Python I used the escpos package. The following shows how the previous example is expressed using this package.
import escpos.printer
p = escpos.printer.Serial("/dev/ttyUSB0", baudrate=34800) # open connection to printer using a serial connection
p.set(align="center")
p.text("Hello\n")
p.set(align="center", bold=True)
p.text("World\n")
p.set(align="center", bold=False)
p.barcode("12345678", "EAN8")
p.cut()
Curating the Printout
Let's get back to the original idea, I want some useful information on the daily printout.
- The current date
- The weather report for that day I got this information from the Bright Sky API. This service only works in Germany as it retrieves the weather from the German Meteorological Service (DWD). To enable a more decent layout I render the weather report to an image and print that image afterward.
- My todos from todoist Todoist offers a python package for fetching tasks, therefore this was absolutely a no-brainer
- My appointments from my iCloud calendar It is possible to access the iCloud calendar with the open-standard CalDAV. With the caldav package, it wasn't that complicated to load the appointments for that day.
- The most important news headlines My favorite news service offers their articles over an RSS Feed - and of cause; there is a python package for parsing RSS feeds
- Some random fact, to end it up By chance, I found an API that provides a random fact on every call. If you're interested in the implementation: The source code is available on gist as a single file.
In order to print the excerpt automatically at 7 PM, I created a cron job using sudo crontab -e
and by adding the line 0 7 * * * python3 /home/pi/scriptel.py