导读:昨天发的打印GitHub票据的详细文章在此,可点击收藏哦。
我在 GitHub 上发布了几个开源项目,其中一些很受欢迎。我倾向于不断优化它们,还不时发布一些问题。一些用户通常会告诉我迷失在我的邮件里,我也会忘掉存储库,只能并将新项目添加到待办事项列表中提醒自己。
每次我看到某个问题消息通知的时候,我会偶尔在便笺上写下问题,但我总想找个借口来简化流程。前几天看到外卖打印小票订单,我就想能不能也利用一下票据打印机,在每次将问题添加到我的一个存储库时,打印出来一个小票。
于是我就开始研究,想不到,它做成了!
我把它公布在推特上,供大家品鉴。没想到反应还是很强烈。
为了让大家能够深入研究,我将向各位展示我使用的详细内容,以及我是如何设置它们的。
硬件清单
下面我们开始!我有一台热敏收据打印机和一些将数据录入其中的方法。我最终使用了以下这些物件:
-
爱普生 TM-T88IV 打印机
-
Raspberry Pi Zero W(树莓派 Zero W)
-
微型 USB 转 USB 适配器
-
USB B 型电缆
我之所以选择爱普生热敏打印机,原因它使用的是 ESC/POS 命令集,它已经建立了各种编程语言的库。还有一个重要原因,它们在二手市场上随处可见,我还可以在网上以相当便宜的价格买到票据用纸。
我需要的另一部分是一些硬件,用于从互联网连接到打印机,然后将实际数据发送给它。
这些设备需要连接到我的电脑上,是一个功能齐全的设备。我有一个旧的Raspberry Pi Zero W,我没怎么太用,一直闲在角落里吃灰。所以我选择它做为打印机接口板。
Raspberry Pi只有一个微型 USB 端口,所以我通过适配器和 USB Type-B 电缆将它们连接到票据打印机。
将数据发送到打印机
现在,我们已经连接了打印机。
现在我需要一种方法从Raspberry Pi向打印机发送数据。可以使用 Node 或 Python 等编程语言完成,我是一名 PHP 开发人员,而且我喜欢扩展编程语言的原有限制,也会努力做到这一点。
对我来说挺幸运的,有一个非常可靠的PHP库可以用于处理 ESC/POS 命令。
在我写代码之前,必须确保打印机可以被于我的程序调用。我在 Raspberry Pi 上使用 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。
如果用户不属于dialout组,我现在尝试将它们添加到里面:
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 的文件
,并添加了以下内容:
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();
现在我们来运行它,当然是CLI模式,我所要做的就是让 PHP ,使用 root 权限执行:
sudo php index.php
如果一切顺利,“Hello,World”将打印在票据上,跳过两行后小票将被剪断。
工作原理非常简单。
创建一个新的FilePrintConnector对象connector,连接的是/dev/usb/lp0,它是
打印机连接的 USB 适配器。随后使用的printer实例 ,(如 text()
, feed()
, cut()方法
) 通过该实例连接将与这些操作关联的命令传输到打印机处理。
注意:如果发送到
/dev/usb/lp0
或类似的情况下收到有关权限的错误,请运行sudo chmod +777 /dev/usb/lp0,然后再看
是否可以修复。
接下来继续与 GitHub 连接,并使用一些真实数据来填写小票。
连接到 GitHub
GitHub 使用webhooks可以很容易地监听 repos 上的事件。
通过转到我的存储库的一个设置页面并导航到 webhook 部分,我可以创建一个hooks,该hooks将在给定操作上发布到特定 URL地址。
我的目标是在创建新新问题时打印一张小票,所以选择“问题”部分,另外我还将数据类型设置为 JSON,因为这是我喜欢用的数据格式。
在继续之前,我需要一个 GitHub 确认能将该 POST 请求发送到指定 URL 。首先,我通过 ssh 连接到 Raspberry Pi ,在该项目目录中加入 -S 参数启动本地 PHP 服务器:
sudo php -S 127.0.0.1:8000
现在它已经正常运行了,接下来需要一种方法来访问Raspberry Pi 的那个端口,而它是在我的本地局域网络上。我不想暴露我家的 IP 地址或创建穿透路由器的通道。
最后我用ngrok隧道,暴露出有用的端口。
ngrok http 8000
加载完毕后,我复制提供的 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 的存储库,创建一个新问题,然后等待打印机打印出票据。
以上代码,可以到作者的GitHub查看:https://github.com/aschmelyun/github-receipts
总结
我们还可以通过几种不同的方式对其进行扩展。
对于小票本身,还可以添加二维码直接链接到 GitHub 上的问题。还可以从问题本身添加更多详细信息,例如标签和严重性等属性。
你还可以使用此概念来处理来自 webhook 或通过 API 请求的任何数据。就像从 Jira 或 Bugsnag 等应用程序、生产机中应用程序抛出的异常,甚至是每日待办事项和购物清单!
你怎么看?如果对如何改进有任何想法,或者只是有问题或评论,请在下面的讨论中告诉我。
作者:Andrew Schmelyun
编译:洛逸
来源:21CTO
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/254850.html