Shotland Drink Rating Module

The goal is to be able to print a receipt with a QR Code when ordering a drink. From the qr code you go to a website to rate that specific drink. The receipt is necesary because i want the user to be able to rate the drink on their phone after consuming it, that way they can enjoy the drink and do not have to worry about a qr code on the screen that needs so stay open until then.


How to setup the bill printer

  • Connect the printer to your network. It will print out its ip adress and network information.
  • You can access admin interface by going to its ip adress. Default Username and Password are epson and epson.
  • If you have a wireless adapter for your printer you can configure WIFI.
  • Either setup your Router to assign a static IP-Adress to the printer or setup a static IP-Adress on the printer.
  • For best practice update the firmware.

Python Code example

Generate QR Code

The code saves the qr code to the codes directory. If a qr code with that id already exists it skipps the generation step.

import qrcode
import os

output_dir = os.path.join(os.path.dirname(__file__), 'codes')
qr_filename = f'qrcode_{drink_id}.png'
qr_path = os.path.join(output_dir, qr_filename)

if not os.path.exists(qr_path):
    qr_data = f"https://url.example?id={drink_id}"
    qr = qrcode.QRCode(
    qr_image = qr.make_image(fill='black', back_color='white')

Talk to Bill Printer

This code checks if the required port of the printer is reachable and prints a title, the QR-Code and cuts the paper afterwards.

from escpos.printer import Network
import socket

printer_ip = "your-printer-ip"

def is_printer_reachable(ip, port=9100, timeout=1):
    """Check if the printer is reachable by attempting a socket connection."""
        with socket.create_connection((ip, port), timeout):
            return True
    except (OSError, socket.timeout):
        return False

if is_printer_reachable(printer_ip):
        p = Network(printer_ip)
        # Center text
        p.text(f"My Title\n")
        # Center QR Code 1
        # Cut the paper
    except socket.error as e:
        print(f"Error connecting to printer: {e}")
    print(f"Printer at {printer_ip} is not reachable. Please check the network connection.")


Next I´ll need to write a webapp where a user can rate a drink. I am thinking of going overkill: I only want legitimate ratings from users that actually ordered a drink but i want to do it without user authentication and it should also work with Shotland offline and not connected to the Internet. (The Ratings page should be avalible over the internet.) I am thinking about implementing a Public and Private Key system: I generate a Public and Private Keypair on Shotland. For every Rating QR-Code I generate a Key signed by the private Key of shotland which will be passed on as a path parameter. On the Webapp Rating site I will validate the authenticity of the key with the public key from Shotland. To ensure that a key does not get used twice I will put it on a blocklist (on the Webapp) once a Rating is submitted. What do you think about that approach? Is it overkill? Could I do it more overkill? Write your thoughts in the comments!

If you want to learn more about Shotland checkout the Shotland Overview Page.

Notify of
Inline Feedbacks
View all comments
Scroll to Top