Encomende o monitor em vez de uma impressora térmica de cozinha

Monitor de pedidos

Uma pequena busca para substituir uma impressora de pedidos de cozinha em um restaurante por um monitor de 24 "com pedidos de raspberryPi durante a noite. Isso é verdade para quase todos os sistemas erp (todos os sistemas 1C modernos em equipamentos comerciais suportam impressoras de recibos, da mesma forma que em outros sistemas).

Observação


Em restaurantes e cafés, as impressoras de pedidos (impressoras de "marca") são usadas com mais frequência para imprimir pedidos na cozinha. São pequenas impressoras térmicas (parentes de caixas registradoras), mas sem unidades fiscais, e geralmente têm um botão - enrolamento de fita. Anteriormente, as impressoras térmicas eram conectadas principalmente a sistemas como o FrontOffice através de uma porta COM, mas há cerca de 10 anos a situação mudou, o suporte a Ethernet apareceu nas impressoras.

Experiência


As impressoras, encontradas no trabalho dos fabricantes Shtrikh-M, Posiflex, Sam4s, são do mesmo tipo, usam o protocolo RAW (One-way Protocol) para impressão. Eles possuem pequenos servidores Web com configurações para velocidade de impressão, especificações de portas, codificações, funcionalidade adicional e configurações de rede. Alguns modelos têm a capacidade de conectar um scanner de código de barras para receber notificações sobre a disponibilidade de pratos (envie o código de barras para a rede). O custo do dia atual para modelos de orçamento começa em 10 tr. e pode atingir até 30 tr na Epson. Expectativa de vida em uso intensivo a partir de alguns anos. As principais causas de falha são: quebra do cortador de papel, graxa (cobre a impressora por fora e parcialmente os mecanismos internos), falha da cabeça térmica, secagem dos rolos e das engrenagens de plástico e impressoras sendo inundadas com líquidos. O reparo e a substituição de elementos representam 50% do custo da impressora e, claro, o consumível é papel térmico.

Desafio


Portanto, de acordo com a cozinha e a administração, em vez da próxima impressora térmica com falha, foi montado um monitor com um raspberry pi 3 B com um cartão SD de 2 GB.
A principal tarefa não é fazer alterações no sistema FrontOffice e o software não deve diferir da impressora de recebimentos / pedidos.

Software de garçons FrontOffice Shtrikh-M, o Shtrih-600 é especificado como a impressora de pedidos. Anteriormente, quando as impressoras russas mudaram para coreano, a página de código na qual os pacotes são transmitidos é a porta 9100 do Windows-1251.

Seleção e configuração do SO


Como um mini-PC será o Raspberry Pi 3 Modelo B, implementaremos nele o leve sistema Raspbian Stretch Lite .

Vamos fazer um pequeno ajuste: entregaremos o gerenciador de janelas do openbox, o gerenciador de login do LightDM ao sistema, configuramos o login automático, ocultamos o log de download.

Um pouco de análise


A seguir, criaremos um servidor de soquete simples para descobrir como as informações são codificadas no pacote e o que geralmente é enviado para a impressora térmica.

#!/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() 

O software FrontOffice envia dados em um pacote no qual um pacote especial voa. caracteres antes e depois da parte principal. As informações de referência sobre fontes e seu tamanho são codificadas com caracteres que não estão na codificação utf8. Cada linha é seguida por / r / n. Foi possível escrever uma função filtrando caracteres especiais, mas temos uma noite e, na "marca", o início é muito bem separado por uma sequência de asteriscos, e o final por uma sequência de caracteres negativos. Adicione uma muleta, descarte caracteres especiais no início e no final, decodifique em utf8. Na janela do console, recebemos o recibo, como na impressão na "marca" da impressora.

Arquitetura de aplicativos futuros


Vamos dar uma olhada na arquitetura do aplicativo.

  1. Um servidor de soquete que está constantemente aguardando recepção.
  2. Servidor web.
  3. O aplicativo de visualização é um navegador com tela cheia.
  4. Um sistema de mensagens entre um servidor de soquete e um servidor da web.

Produção


Resolveremos o primeiro e o quarto pontos adicionando o servidor de soquete descrito acima - redis - com um armazenamento de valor-chave, com vistas a futuras melhorias (canais - assinaturas), ao longo do caminho reduziremos o desgaste do cartão SD. E adicione um sinal - uma notificação sobre a chegada de um novo pedido, vamos jogar através de HDMI nas colunas do monitor. A saída de som é ativada via 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() 

No segundo parágrafo, enviaremos o servidor da Web para o balão com atualização automática a cada 15 segundos (por enquanto essa é a opção mais fácil), marcar socketio na lista de tarefas e a fila poderá ser de aipo ou redis. Classificamos todos os pares de valores-chave disponíveis e os exibimos na página. Ao clicar na "marca", removeremos dos redis e da área de trabalho, respectivamente.

 # -*- 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') 

Adicionar modelo 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> 

Havia o item 3, criaremos o navegador mais mínimo sem botões de 13 linhas.

 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_()) 

Em seguida, você precisa criar serviços para executar todos os scripts escritos acima.
Ou registre-os rapidamente no arquivo openbox de inicialização automática.

Resultado
Monitor de pedidos de cozinha

Source: https://habr.com/ru/post/pt418961/


All Articles