窓口の受付番号システムをつくる・Python編(ダウンロード可)

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、前回の「窓口の受付番号システムをつくる・Python編」に引き続いての第2弾Python編です。

※もしまだ前回記事を読んでいない方はそちらから読み進めてください。

では、Laravelで作成した受付番号発行システムの番号札・印刷部分をPythonで作っていきます。

ぜひ皆さんのお役に立てると嬉しいです😊✨

「2回に分けた記事は初めてなんで、
バランスが7:3になっちゃいました😂」

Pythonからプリンタを操作できるようにする

では、Amazonで購入した以下の感熱紙プリンタをPythonから操作できるようにしていきます。

・・・といっても、すでに同じプリンタでチャレンジした方がいらっしゃったようで、以下のページを参考にさせていただきました。(素晴らしい記事、ありがとうございます❗)

Raspberry Pi を使ってレシートプリンタから印刷してみる

パッケージをインストール

では、PythonからESC/POS形式の命令文が実行できるように次のパッケージをインストールしましょう。

pip install python-escpos

プリンタのUSB番号を取得する

プリンタをUSBで接続して、次のコマンドを実行します。

lsusb

すると、USB接続情報の一覧が表示されるので、その中から、

Winbond Electronics Corp. Virtual Com Port

と書かれている行を探してください。
そして、その行のIDと書かれているものがプリンタのIDになります。

※なお、今回は0416:5011でした。

テスト印刷してみる

では、とりあえずレシートが印刷できるか確認してみましょう。
次のPythonコードを作ります。

issue_number_tag.py

from escpos.printer import Usb

p = Usb(0x0416, 0x5011, 0)
p.text("Hello World\n")
p.cut()

そして、以下のコマンドで実行してください。

sudo python issue_number_tag.py

このように印刷できればうまく接続できています。

受付番号を発行する

では、ここから受付番号をレシートに印刷する方法になります。

実装方法としては、Laravel側に専用フォルダをつくり、Pythonでそのフォルダを監視する方法で実装します。

つまり、流れとしては次のようなものになります。

  1. Laravelで新規受付番号を発行したとき、専用フォルダにJSONファイルを作成する
  2. 監視中のPythonスクリプトがJSONファイルを検知したらプリンターで受付番号を印刷する
  3. 印刷が完了したらJSONファイルは削除する

では、実際にやっていきましょう❗

Laravel側の作業

receptionsテーブルにデータが追加されたら自動的にJSONファイルを作成するReceptionCreatedイベントをつくりましょう。

以下のコマンドを実行してください。

php artisan make:event ReceptionCreated

そして中身を次のように変更します。

<?php

namespace App\Events;

use App\Reception;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Str;

class ReceptionCreated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Reception $reception)
    {
        $filename = $reception->id .'-'. Str::random() .'.json';
        $path = 'reception_created/'. $filename;
        \Storage::put($path, $reception->toJson());
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

やっていることは、新規作成したデータを「/storage/app/reception_created」フォルダにJSONとして保存しているだけです。

では、このイベントが有効になるようにReceptionモデルにセットしておきましょう。

/app/Reception.php

<?php

namespace App;

use App\Events\ReceptionCreated;
use App\Events\ReceptionCreating;
use Illuminate\Database\Eloquent\Model;

class Reception extends Model
{
    protected $dispatchesEvents = [
        'creating' => ReceptionCreating::class,
        'created' => ReceptionCreated::class // 👈 追加
    ];
}

これで新規受付番号が発行されたら自動的にファイルが作成されることになります。

Python側の作業

では、一番最初に作ったissue_number_tag.pyをカスタマイズして「/storage/app/reception_created」を監視するコードをつくっていきます。

from escpos.printer import Usb
import os
import json
import time

FOLDER_DIR = '/PATH/TO/YOUR/LARAVEL/storage/app/reception_created';
p = Usb(0x0416, 0x5011, 0)

print('Listening...');

while 1:
    time.sleep(3)
    for filename in os.listdir(FOLDER_DIR):
        json_path = FOLDER_DIR +'/'+ filename
        with open(json_path) as json_file:
            json_data = json_file.read()
            receptions = json.loads(json_data)
            reception_type_id = receptions['type_id']
            reception_number = receptions['reception_number']
            print_text = "\nRecection Type: "+ str(reception_type_id) +"\nNo. "+ str(reception_number)
            os.remove(json_path)
            p.text(print_text)
            p.set('CENTER')
            p.cut()

この中では、Laravel側で保存したJSONファイルの中身を読みとり、そこに保存されている情報をもとにプリンターへ出力するようにしています。

※なお、今回はテストですので英数字だけ印字しますが、日本語も出力できるようです。その場合、日本語はフォントから一旦画像をつくり、その画像をプリントする流れになります。詳しくは、先ほどのcles::blogさんのページをご覧ください。(ラズベリーパイを使っていて、とてもcoolです😊👍)

テストしてみる

では、PythonLaravelのフォルダを監視しつつ受付番号が発行されたらプリンターで自動印刷できるかチェックしてみましょう❗

まず、Pythonissuse_number_tag.pyを実行します。

sudo python issue_number_tag.py

すると、次のような表示になります。

そして、今度はブラウザ側から「/reception/number_tag」にアクセスします。

では、左上の「新規口座開設」ボタン(Reception Type ID: 1)をクリックしてみましょう。

プリンターが「新規口座開設」IDの1と受付番号の1をプリントアウトしてくれました❗

では、続いてもう一度「新規口座開設」ボタンをクリックしてみましょう。

はい❗今度は「No. 2」として印刷されました。
成功です😊✨

ダウンロードする

お待たせしました。
今回2回に渡って開発してきたソースコードを以下からダウンロードできます。

Laravel + Python で窓口の受付番号システムをつくる

※ただし、フォルダのパスやマイグレーションなどはご自身で実行してください。

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回は2回に渡って受付番号を管理するシステムを(リーズナブルな値段で実装できるように)開発してみました。

なお、今回のシステムを導入する場合のコストをまとめてみました。

  • OS: Ubuntu(Linux)なら費用は不要
  • 基本的なシステムのコード: 私のコードはMITライセンスで公開しています
  • プリントアウト費用: Amazonで4,499円(2020.4.27現在)
  • パソコン:ラズベリーパイなら1万円以下。さらにすでにお持ちのパソコンやiPadも利用できます。
  • 後は、カスタマイズ・設置費用など

企業の皆様、コスト削減をご希望でしたらお力になれるかと思います。
ぜひお問い合わせからお問い合わせください。

ではでは〜❗

「ブラウザでできることが増えてるので、
もっとコスト削減できそうです❗」

このエントリーをはてなブックマークに追加       follow us in feedly