我为 GitHub 问题制作了一台收据打印机
我在 GitHub 上有很多业余项目。有些还挺热门的,我时不时会发一些问题。但问题是,它们通常会被淹没在我的邮件堆里,或者我忘记浏览我的代码库,把新项目添加到待办事项列表中。
每当我看到问题通知时,我都会偶尔在便签上记录新的问题,但我一直想找个借口来进一步简化流程。前几天,我去买外卖时看到一台收据打印机自动打印订单,于是我就想,每次我的代码库里有新问题添加时,能不能用一台收据打印机打印一张票据。
剧透警告,它成功了!
那么让我们深入研究一下,我将向您展示我到底使用了什么,以及如何设置它!
硬件列表
首先,我需要一台热敏收据打印机,以及一些将数据导入打印机的方法。我最终使用了:
- 爱普生TM-T88IV
- 树莓派 Zero W
- Micro USB 转 USB 适配器
- USB Type-B 线缆
我选择爱普生热敏打印机的原因是它使用 ESC/POS 命令集,而各种编程语言都有相应的库。而且,这种打印机在二手市场上随处可见,我甚至在 eBay 上以相当公道的价格买到了一台,还附赠了一些收据纸。
我还需要某种硬件来连接互联网和打印机,并方便实际的数据发送。我可以直接把它连接到我的电脑上,但我希望它能成为一个功能齐全的设备,可以一直闲置在角落里。我手边有一块旧的Raspberry Pi Zero W,暂时不用,所以我会选择它。
由于 RPi Zero 只有一个微型 USB 端口,因此我将使用适配器以及 USB Type-B 电缆将其连接到收据打印机。
发送数据到打印机
好了,打印机已经连接好了,Raspberry Pi 也准备就绪,但现在我需要一种方法将数据从Raspberry Pi 发送到打印机。这可以用 Node 或 Python 轻松实现,但由于我是一名 PHP 开发人员,并且喜欢突破语言的限制,所以我会尝试一下。幸运的是,PHP 中有一个非常可靠的 ESC/POS 命令库。
不过,在编写任何代码之前,我必须确保我创建的程序可以使用打印机。由于我在树莓派上使用 Ubuntu,所以我应该可以通过/dev/usb/lp0
(或其他 lp#) 访问它。但这可能需要一些准备工作。
首先,我将在连接打印机的设备(我使用的是 Raspberry Pi)上打开一个终端。我将运行以下命令,从打印机连接中lsusb
获取产品 ID和供应商 ID 。它返回的内容如下:
Bus 002 Device 001: ID 04b2:0202 Epson TM-T888IV Device Details
接下来,我创建一个 udev 规则,允许dialout组的用户使用打印机。我创建该文件/etc/udev/rules.d/99-escpos.rules
并添加以下内容:
SUBSYSTEM=="usb", ATTRS{idVendor}=="04b2", ATTRS{idProduct}=="0202", MODE="0664", GROUP="dialout"
确保将供应商和产品 ID 的十六进制值替换为我从中返回的值lsusb
。
如果我的用户不属于拨出组,我现在尝试将他们添加到该组中:
sudo usermod -a -G dialout pi && sudo usermod -a -G dialout root
最后,我必须重新启动 udev:
sudo service udev restart
现在连接已经准备好了,我可以开始编写一些代码来测试一下了。首先,我需要用 Composer 引入之前提到的那个库:
composer require mike42/escpos-php
安装完成后,我需要编写一些代码来将数据发送到打印机。我将创建一个名为 的文件index.php
,并添加以下内容:
<?php
require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\Printer;
$connector = new FilePrintConnector('/dev/usb/lp0');
$printer = new Printer($connector);
$printer->text('Hello, world!');
$printer->feed(2);
$printer->cut();
所以现在要运行它,我要做的就是使用 PHP 和 root 权限执行脚本:
sudo php index.php
如果一切顺利,“Hello, world!”将会打印在收据上,但会跳过两行,然后收据就会被剪掉。这一切的工作原理非常简单。
会创建一个打印连接器,连接到“文件” /dev/usb/lp0
,即打印机所连接的 USB 适配器。后续使用的打印机命令(text()
、feed()
、cut()
)会通过该连接将与这些操作相关的原始命令传输到打印机。
注意:如果在发送时出现有关权限的错误
/dev/usb/lp0
或类似情况,请尝试运行sudo chmod +777 /dev/usb/lp0
并查看是否可以解决问题。
使用这些方法,我可以继续将其与 GitHub 连接并使用一些实际数据填充收据。
连接到 GitHub
GitHub 使用webhook轻松监听代码库上的事件。前往我的某个代码库的设置页面,找到 webhook 部分,创建一个钩子,该钩子会在指定操作时 POST 到特定的 URL。就我而言,我希望在创建新问题时打印出工单,因此我选择“问题”部分。我还将数据类型设置为 JSON,因为我喜欢使用 JSON。
但在继续之前,我需要一个 GitHub 可以发送 POST 请求的 URL 。首先,我通过 ssh 回到 Raspberry Pi,并在项目目录中使用 -S 标志启动本地 PHP 服务器:
sudo php -S 127.0.0.1:8000
现在它已经运行起来了,我需要一种方法来访问我的树莓派上的那个端口,即使它在我的本地网络上。我实在不想暴露我家的 IP 地址,也不想担心通过路由器创建隧道。所以,我最终使用ngrok来建立隧道连接到暴露的端口。
ngrok http 8000
加载完成后,我复制提供的 https url,并将其粘贴到 GitHub webhook url 字段中。一切看起来都很好,然后我保存了 webhook。保存后,应该会有一个测试请求发出,ngrok 会接受该请求,并将其隧道传输到本地 PHP 服务器,然后会打印出另一个Hello, world!消息。
现在我准备实际使用来自 GitHub 的传入请求来构建票证。
最终代码
现在,我将对之前的代码进行一些修改。首先,我应该丢弃所有非 POST 请求。因此,在初始化 FilePrintConnection 之前,我添加了以下几行代码:
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
return 'Error: Expecting POST request';
}
在 FilePrintConnection 和 Printer 初始化之后,我将把来自 GitHub 的整个 JSON 请求解码为关联数组:
$data = json_decode(file_get_contents('php://input'), true);
现在,我可以使用之前的打印机方法和 GitHub 中的数据数组来创建我想要的收据了!使用 Escpos 库,格式化文本需要大量重复的代码。举个小例子,以下是带有粗体下划线的问题标题以及纯文本正文的样子:
$printer->setUnderline(true); // start underlined text
$printer->setEmphasis(true); // start bolded text
$printer->text($data['issue']['title']);
$printer->setEmphasis(false); // stop bolded text
$printer->setUnderline(false); // stop underlined text
$printer->text($data['issue']['body']);
现在要测试它,我要做的就是转到我设置 webhook 的存储库,创建一个新问题,然后等待打印机传送票证 :magic:。
总结和后续步骤
好了,接下来我们该怎么做呢?这确实是一个简单的概念验证,但我们可以通过几种不同的方式对其进行扩展。
对于工单本身,可以添加二维码,直接链接到 GitHub 上的问题。您还可以添加问题本身的更多详细信息,例如标签和严重程度。
您还可以使用这个概念来处理来自 webhook 或 API 请求的任何数据。例如,从 Jira 或 Bugsnag 等应用程序打印票据、从生产应用程序抛出的异常,甚至是每日待办事项和购物清单!
那么,你觉得怎么样?如果你对如何改进这个设置有什么想法,或者只是有疑问或评论,请在下面的讨论中或在我的推特上告诉我!
鏂囩珷鏉ユ簮锛�https://dev.to/aschmelyun/i-built-a-receipt-printer-for-github-issues-51b7