先日見つけた記事、
ADHDの先延ばし癖を「レシートプリンター」を使ったライフハックで克服できたというエピソード
ADHDの先延ばし癖を「レシートプリンター」を使ったライフハックで克服できたというエピソードゲームやSNSならいくらでもやり続けられるのに、仕事のタスクや日常の家事などはどんどん先延ばししてしまうという人もいるはず。ADHDに関連した先延ばし癖に悩み、20年以上にわたり生産性を高める方法を試行錯誤してきたというローリー・エロー氏が、「レシートプリンターを使ったライフハックで先延ばし癖を克服した方法」について解...
こちらを読んでいたら、色々と応用できそうだったので、自宅にもレシートプリンター(サーマルプリンター)を設置することにしました。
最終的な運用方法としては、常時稼働のラズパイサーバーにサーマルプリンターを接続しておき、LAN経由で印刷内容を送信(音声やLINEボットなど)できるようにします。
サーマルプリンター選びはESC/POSがキモ
Amazonなどを見ているとサーマルプリンターは数千円から色々と売っていますが、今回の用途だと、専用のアプリやドライバーが必要なものは面倒 or 不可なのでNG。
サーマルプリンターの規格として、エプソンが開発したESC/POSコマンドという物があります。こちらはドライバーが不要なので、多くの環境で使えて便利ですね。
このESC/POSに準拠した実装が行われているサーマルプリンターを買えば良いというわけです。
こういったガジェットを漁るとき私は専らアリエクで探しますが、普通に購入する分には品揃えや価格の面でAmazonもさほど変わらないですね。
とにかくESC/POSに準拠・対応・互換、的なものを購入しておけば問題ないと思います。

とりあえずラズパイでサーマルプリンターを動かす
ではラズパイでテストプリントするところまでいきましょう。
タイトルにもありますが、今回はRaspberry Pi 2 Model Bというかなり古いものを使用しています。(2015年位に買いましたが、サーバー用途であればまだまだ現役です。)
OSは32bit向けの最新のものを入れてあります。
ラズパイとはUSB接続で動かしますが、バスパワーで動かすタイプのプリンターだと電流が不足します。
journalctlコマンドでUndervoltage detected! とか出ていたら、電源を供給できるタイプのUSBハブなどを使用しましょう。
接続したら、lsusbコマンドでそれっぽいデバイスが表示されていることを確認。
USB接続で正常にデバイスが認識していることを確認したら、 /dev/usb/lp0というファイルがあるかどうか確認します。
lp0(line printer No.0の略)は、プリンターとやり取りをするためのデバイスファイルなので、直接書き込んだデータがプリンターに送信されます。
試しに以下を実行してみます。
$ echo "test" > /dev/usb/lp0
低レイヤな操作ですが、プリンターが動くことを確認できます。
正常に接続ができていることを確認したら、実際に運用するサーバー側のスクリプトを作っていきましょう。
やることとしては、
- システム側で必要なライブラリとフォントをインストール
- pythonの必要なライブラリをインストール
- udevルールを設定
- テストスクリプトを実行
という流れです。
各種ライブラリ等をインストール
まず、pythonのライブラリを入れるために必要なパッケージ(ライブラリとフォント)をインストールします。
$ sudo apt install libjpeg-dev zlib1g-dev fontconfig fonts-noto-cjk
次にpythonの仮想環境でライブラリをインストールしていきます。
# 仮想環境(venv)を作成
python3 -m venv venv
# 仮想環境を有効化
source venv/bin/activate
# ライブラリインストール
pip install python-escpos
そして、pythonスクリプトからUSBデバイスへ接続するために、udevルールを設定します。
下記ファイルを作成して、
/etc/udev/rules.d/99-escpos-printer.rules
下記の1行を保存しておきます。
SUBSYSTEM=="usb", ATTR{idVendor}=="{ベンダーID}", ATTR{idProduct}=="{プロダクトID}", MODE="0666", GROUP="dialout"
ベンダーIDとプロダクトIDは、lsusbコマンドの
ID {ベンダーID}:{プロダクトID}
から確認できます。
設定を保存したら、下記コマンドでudevルールをリロードしたあと、プリンターのUSBケーブルを一度抜き差しして接続に反映させます。
sudo udevadm control --reload-rules
pythonスクリプトを作成
準備は整ったので、実際の運用に向けてpythonスクリプトでテスト印刷をします。
コードは下記です。udevで設定したIDとフォントの部分は適宜調整してください。
from escpos.printer import Usb
from PIL import Image
# プリンターのベンダーIDとプロダクトID
# journalctlのログやlsusbコマンドで確認した値
vendor_id = 0x1234
product_id = 0x5678
# ----------------------------------------------------
# プログラム本体
# ----------------------------------------------------
try:
# USB接続のプリンターを初期化
p = Usb(vendor_id, product_id)
# ------------------ テキスト印刷 ------------------
p.text("Hello, ESC/POS printer!\n")
p.text("--- End of text ---\n\n")
# ------------------ 画像印刷 ------------------
# 空白の画像を作成
img = Image.new("1", (300, 100), 255)
# 画像にテキストを描画
from PIL import ImageDraw, ImageFont
draw = ImageDraw.Draw(img)
try:
# Raspberry Piにインストールされている日本語フォントのパスを指定
# fc-list :lang=ja で確認したパスに修正してください
font_path = "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"
font = ImageFont.truetype(font_path, 20)
draw.text((10, 30), "画像として印刷", font=font)
except IOError:
# フォントが見つからない場合は、フォント指定なしで描画
draw.text((10, 30), "画像として印刷 (Font not found)")
# 画像を印刷
p.image(img)
p.text("--- End of image ---\n\n")
# 印刷が完了したことをターミナルに表示
print("印刷が正常に完了しました。")
except Exception as e:
# エラーが発生した場合、ターミナルに表示
print(f"印刷中にエラーが発生しました: {e}")
finally:
# 処理が終了したら、プリンター接続を閉じる
try:
p.close()
except UnboundLocalError:
pass
仮想環境を有効にした状態で上記のスクリプトを実行すれば、テスト内容が印刷されると思います。
テキストとして日本語を印刷するには、プリンター側で対応が必要(安いプリンターは基本的に非対応)だったので、日本語フォントから文字を画像として印刷するようになっています。
あとはよしなに
ここまでできれば、あとは外部からなんらかの形でスクリプトを実行すれば良いので、お好みの方法で入力部分を実装してください。
私は自宅に設置して誰でも印刷できるようにし、家事などのクエストボード的なものとして運用しています。
まとめ
レシートが身近なものすぎて、自宅用のメモを印刷して使うという発想がありませんでした。
実際使ってみるとかなり便利です。
ちなみにアリエクでキャンペーンやコイン割を駆使すれば、2000円で変えるので、安く済ませたい方はお試しあれ。
コメント