Add Epson TM-T20II receipt printing (title/body/QR, no ESC/POS knowledge needed)
deploy / deploy (push) Successful in 8s

Custom ReceiptBuilder instead of the escpos gem -- its diacritics handling
needed the same manual UTF-8->CP852 encode call anyway, based on earlier
experiments in ~/test/epson/.
This commit is contained in:
randy committed 2026-09-13 10:42:52 +02:00
1 parent 5c06f725f0
commit afae57aff4
4 files changed
+154

No files matched your search

+30
View File
@@ -3,6 +3,7 @@ require 'sinatra'
require "sinatra/reloader"
require 'tmpdir'
require 'net/http'
require_relative 'lib/receipt_builder'
set :protection, :except => :frame_options
set :environment, :production
@@ -21,6 +22,8 @@ PRINTER_DPI = 203 # DatamaxONeil E4204B Mark III native head resolution
PRINTER_DARKNESS = 8 # lower than factory default to stop thermal dot-gain from fusing barcode bars
TEST_LABEL_PDF = File.join(File.dirname(__FILE__), 'test-label.pdf')
PRINTER_DEVICE_EPSON = '/dev/usb/lp_epson' # see /etc/udev/rules.d/99-epson.rules
BROTHER_PRINTERS = {
'ql560' => { port: 8560, label: 'Brother QL-560' },
'ql700' => { port: 8700, label: 'Brother QL-700' },
@@ -88,6 +91,19 @@ helpers do
File.open(PRINTER_DEVICE, 'wb') { |f| f.write(data) }
end
# Builds a simple receipt (bold centered title + left-aligned body,
# optional QR code) so callers don't need to know ESC/POS escape codes.
def print_receipt(title:, body:, qr: nil)
receipt = ReceiptBuilder.new
receipt.align(:center).bold.text("#{title}\n").bold(false) unless title.to_s.empty?
receipt.align(:left).text("#{body}\n") unless body.to_s.empty?
unless qr.to_s.empty?
receipt.align(:center).feed(1).qr(qr).feed(1)
end
receipt.feed(3).cut
receipt.print!(PRINTER_DEVICE_EPSON)
end
# Transparently reverse-proxies the current request to one of the
# brother_ql_web instances, so all three printers (web UI and API alike)
# are reachable through this single sinatra port instead of their own
@@ -187,6 +203,20 @@ post '/test-print' do
redirect '/upload'
end
get '/epson' do
erb :epson
end
post '/epson/print' do
begin
print_receipt(title: params[:title].to_s, body: params[:body].to_s, qr: params[:qr].to_s)
flash 'Sent to Epson printer', 'success'
rescue => e
flash "Epson print failed (#{e.message})", 'danger'
end
redirect '/epson'
end
get '/brother' do
@printers = BROTHER_PRINTERS
erb :brother_picker