订购监视器,而不是厨房热敏打印机

订单监控

一个关于在晚上用raspberryPi订单的24英寸显示器替换餐厅的厨房订单打印机的小任务。这几乎适用于所有erp系统(商用设备中的所有现代1C系统都支持收据打印机,与其他系统类似)。

备注


在饭店和咖啡馆中,订单打印机(“品牌”打印机)最常用于在厨房打印订单。 这些是小型热敏打印机(相对于收银机),但是没有财务驱动器,并且它们通常具有一个按钮-卷带。 以前,热敏打印机主要通过COM端口连接到FrontOffice等系统,但是大约10年前情况发生了变化,打印机中出现了对以太网的支持。

体会


在制造商Shtrikh-M,Posiflex,Sam4s的工作中发现的打印机属于同一类型,它们使用RAW协议(单向协议)进行打印。 他们有小型Web服务器,可以设置打印速度,端口规格,编码,其他功能和网络设置。 某些型号可以连接条形码扫描仪,以通知有关餐具准备情况的信息(将条形码发送到网络)。 预算模型当天的费用从10 tr开始。 并可以在Epson上达到30 tr。 密集使用的预期寿命为几年。 造成故障的主要原因是切纸器破裂,油脂(打印机覆盖外部,内部有部分机械),热敏头故障,滚筒和齿轮塑料变干以及打印机被液体淹没。 元素的维修和更换是打印机成本的50%,当然,消耗品是热敏纸。

挑战赛


因此,与厨房和管理部门达成协议,安装了带有树莓派3 B和2 GB SD卡的显示器,而不是下一个出现故障的热敏打印机。
主要任务是不对FrontOffice系统进行更改,并且使软件与收据/订单的打印机相同。

FrontOffice Shtrikh-M,Shtrih-600服务员的软件被指定为订单打印机。 早先,当俄罗斯打印机改为韩文时,事实证明,发送数据包的代码页是Windows-1251端口9100。

操作系统选择和设置


由于Raspberry Pi 3 Model B是微型PC,我们将在其中部署轻量级的Raspbian Stretch Lite系统

我们将做一些调整:将openbox窗口管理器,LightDM登录管理器交付给系统,配置自动登录,隐藏下载日志。

一点分析


接下来,我们将构建一个简单的套接字服务器,以找出信息在数据包中的编码方式以及通常发送到那里的热敏打印机的信息。

#!/usr/bin/env python # -*- coding: utf-8 -*- import socket sock = socket.socket() sock.bind(('', 9100)) sock.listen(1) while True: conn, addr = sock.accept() data = conn.recv(16384) print(data) # print(((data.rsplit('*',1)[1]).rsplit('- -',9)[0]).decode('cp1251').encode('utf8')) # clear_data = ((data.rsplit('*',1)[1]).rsplit('- -',9)[0]).decode('cp1251').encode('utf8') conn.close() 

FrontOffice软件将数据发送到一个包含特殊数据包的数据包中。 主要部分前后的字符。 有关字体及其大小的参考信息使用非utf8编码的字符编码。 每行后跟/ r / n。 可以编写一个过滤特殊字符的函数,但是我们有一个晚上,在“标记”中,开头很好地用一串星号隔开,结尾处用一串负号隔开。 添加拐杖,在开头和结尾处丢弃特殊字符,并在utf8中解码。 在控制台窗口中,我们收到收据,就像从打印机在“标记”上打印时一样。

未来的应用架构


让我们看一下应用程序架构。

  1. 一直在等待接收的套接字服务器。
  2. Web服务器。
  3. 查看应用程序是全屏浏览器。
  4. 套接字服务器和Web服务器之间的消息传递系统。

生产量


我们将通过添加上述具有密钥值存储的套接字服务器-redis来解决第一点和第四点,并着眼于未来的改进(渠道-订阅),同时我们将减少sd卡的磨损。 并添加一个信号-关于新订单到达的通知,我们将通过hdmi在监视器列上播放。 声音输出通过raspi-config激活。

 #!/usr/bin/env python # -*- coding: utf-8 -*- import socket import redis import pygame sock = socket.socket() sock.bind(('', 9100)) sock.listen(1) pygame.mixer.pre_init(frequency=44100, size=-16, channels=2, buffer=4096) pygame.mixer.init(44100, -16, 2, 4096) sound = pygame.mixer.Sound("icq.wav") #print(sound.get_num_channels()) r = redis.StrictRedis(host='localhost', port=6379, db=0) n=0 while True: conn, addr = sock.accept() data = conn.recv(16384) print(((data.rsplit('*',1)[1]).rsplit('- -',9)[0]).decode('cp1251').encode('utf8')) sound.play() clear_data = ((data.rsplit('*',1)[1]).rsplit('- -',9)[0]).decode('cp1251').encode('utf8') r.set('data'+str(n), clear_data) n=n+1 conn.close() 

在第二段中,我们将每隔15秒将Web服务器上载到烧瓶,并每15秒自动更新一次(目前这是最简单的选择),在任务列表中标记socketio,队列可能是芹菜或Redis。 我们对所有可用的键值对进行排序,并将其显示在页面上。 通过单击“品牌”,我们将分别从Redis和桌面中删除。

 # -*- coding: utf-8 -*- from flask import Flask, render_template, redirect import os import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) app = Flask(__name__) def kernel_ver(): try: f = open(os.path.dirname(os.path.abspath(__file__)) + '/release.txt') lines = f.readlines() f.close() return lines[0] except IOError as e: return "--" @app.route('/') def index(): d = {} for item in r.keys(): d[item] = (r.get(item)).decode('utf8') return render_template("index.html", release=kernel_ver(), di = d) @app.route('/del/<key>') def delstamp(key): r.delete(key) return redirect("http://192.168.1.80:5000/", code=302) if __name__ == "__main__": app.run(host='0.0.0.0') 

添加jinja模板

 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="refresh" content="30"/> <title>  </title> <link href="http://fonts.googleapis.com/css?family=Reenie+Beanie:regular" rel="stylesheet" type="text/css"> </head> <body> <ul> {% for key in di %} <li> <a href="/del/{{key}}"> <!-- h2>Title #1</h2 --> {% for item in di[key].splitlines() %} <p>{{ item }}</p> {% endfor %} </a> </li> {% endfor %} </ul> </body> </html> 

这里有第3项,我们将成为没有13行按钮的最小浏览器。

 import sys from PySide import QtCore, QtGui, QtWebKit class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.showFullScreen() self.web = QtWebKit.QWebView(self) self.web.load(QtCore.QUrl('http://127.0.0.1:5000')) self.setCentralWidget(self.web) app = QtGui.QApplication(sys.argv) main_window = MainWindow() main_window.show() sys.exit(app.exec_()) 

接下来,您需要创建服务以运行上面编写的所有脚本。
或在自动启动的openbox文件中快速注册它们。

结果
厨房订单监控器

Source: https://habr.com/ru/post/zh-CN418961/


All Articles