やりたかったこと
写真のような、小売店などに設置してあるレシートプリンタを操作してみたいと思ったことありませんか?
たまたまレシートプリンタを使えそうなイベントがあったので、ついでに操作方法をまとめてみました。
なお、本記事ではEPSONのTM-T88Vを使用していますが、EPSONのPOS規格に対応した製品なら概ね同じ手順で操作できるかと思います。
1. 準備
テスト環境
- Windows11
- Python 3.10
レシートプリンタの入手
有名どころはEPSONのTMシリーズだと思います。現行機種のTM-M88IIIやTM-T88VIIはヤフオクでも数万円以上するので、型落ち品であるTM-T88Vを入手しました。購入当初は送料込みで3000円強でした。
型番のうち、TMに続く「M」シリーズは複数の接続インターフェースに対応するモデル、「T」シリーズは単一の接続インターフェースであるモデルです。TM-Mシリーズは小型な上、無線LANやBluetoothなどに対応しているのでお金に余裕があれば買いたかった...。
ちなみにTM-T88Vは同型番で複数種類あり、今回使用したのはUSB接続モデルの製品です。ヤフオクなどではシリアル接続・パラレル接続のものも多く出回っているので注意が必要です。
公式ドライバーの入手と本体設定(必須ではない)
自動カットの設定などができるので一旦入手することをおすすめします。製品によってソフトウェアが異なるので適宜読み替えてください。
- EPSON公式ページからTM-T88V Utilityを入手
- インストール
注意:Windows11の「メモリ整合性」機能と互換性がないので、インストール時にはWindows Defenderから「メモリ整合性」をオフにしておく必要があります。 - EPSON TM-T88V Utilityを起動
TM-T88V Utilityでは本体設定や情報の確認を行えます。
- 自動用紙カット
用紙交換後の紙送り・自動カットの設定ができます。とりあえず「カバークローズ時に用紙を自動カットする」にしておけば便利かと。 - 印刷制御の設定
印字濃度や速度の設定ができます。こだわりがなければ最大値で問題ないかと。
ちなみに任意のロゴを登録し、印刷毎に印字することも可能なようですが、今回使用するライブラリを使用する場合は設定が無視されるようなので割愛します。
設定が終わったらソフトはアンインストールしてしまっても問題ありません。
2. ドライバーの差し替え
公式ドライバーはlibsubに対応していないので、互換ドライバーに差し替えを行います。
- Zadigをダウンロード
- ソフトを起動し、上部メニュー
Options
→List All Devices
にチェック - プルダウンメニューで「EPSON TM-T88V」(接続したプリンターに対応したもの)を選択
-
Driver
欄の矢印右側がWinUSB~
となっていることを確認し、Replace Driver
をクリック
ドライバーのインストールには数分ほどかかります。インストールが完了したらソフトは閉じて問題ありません。
ベンダーIDとプロダクトIDの特定
デバイスマネージャーを開き、ユニバーサルシリアルバスデバイス
の項目に「EPSON」から始まるデバイスが表示されていることを確認します。
次に当該デバイスのプロパティを開き、詳細
タブのプルダウンメニューからハードウェアID
を選択します。
このとき表示されるVID_
、PID_
それぞれに続く4桁がベンダーID、プロダクトIDとなるので16進数としてメモしておきます(写真の場合はベンダーIDが0x04b8
、プロダクトIDが0x0202
)。
3. Pythonライブラリの入手
必要なライブラリをインストールします。
pip install pyusb libusb python-escpos
インターフェース番号の特定(USB接続の場合)
プリンターと接続されているUSBポートの番号を特定するため、先ほど確認したベンダーIDとプロダクトIDを書き換えてから以下コードを実行します。
import usb.util
import usb.core
VENDOR_ID = 0x04b8
PRODUCT_ID = 0x0202
dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)
if dev is None:
raise ValueError("デバイスが見つかりません")
cfg = dev.get_active_configuration()
for intf in cfg:
print("Interface Number:", intf.bInterfaceNumber)
ここまでの手順まで問題無く完了していれば、コンソール上にインターフェース番号が表示されるはずです。
4. テスト印刷
これで設定は完了です!インターフェース番号を書き換えて、早速テスト印刷してみましょう。
from escpos.printer import Usb
VENDOR_ID = 0x04b8
PRODUCT_ID = 0x0202
INTERFACE_NUM = 0
p = Usb(VENDOR_ID, PRODUCT_ID, INTERFACE_NUM, timeout=1000)
p.text("hogehoge\n")
p.qr("https://example.com")
p.cut()
用紙に文字とQRコードが印刷されていれば成功です。
import
部分ではUsb
クラスを利用していますが、ほかにNetwork
やSerial
クラスがあるようです。ご自身のプリンター接続方法に合わせて書き換えてください。
日本語テキストについて
今回利用したpython-escposライブラリは日本語印刷には非対応のため、日本語を指定すると文字化けします(一応文字コードは指定できるものの不具合があり正しく印刷できない)。
日本語に対応したライブラリも存在するものの、長期間メンテナンスされておらず動作確認ができなかったため、forkライブラリを修正したものを作成しました。
pip install git+https://github.com/chansei/python-escpos-jp
当該ライブラリをimportすることで日本語テキストの印刷に対応したjpText
関数が利用できるようになります。
from escposjp import Usb
p = Usb(0x04B8, 0x0202, 0, timeout=1000)
p.jpInit() # 利用前に初期化が必要
p.jpText("テスト印刷")
p.qr("https://example.com")
p.cut()
標準テキストのほかに、Pillowライブラリのimageとしてフォントを埋め込み、画像として印刷する方法もありますが、詳しく解説されている方が居るので割愛します。
おわりに
Windows環境のPythonから印刷した例が少なく、ドライバー周りの処理に苦しみました。
一度動いてしまえば何でも印刷できそうな予感がします。