1
0
Fork 0

cashbox opening - static ip

This commit is contained in:
Tobias Brunner 2018-08-07 20:08:42 +00:00
parent 71ca7132eb
commit af156d5115
2 changed files with 210 additions and 0 deletions

View File

@ -57,6 +57,7 @@ RUN git clone --depth=1 -b 11.0 https://github.com/it-projects-llc/pos-addons.gi
COPY hw_screen_main.py /usr/lib/python3/dist-packages/odoo/addons/hw_screen/controllers/main.py
COPY hw_screen_main.py /usr/lib/python2.7/dist-packages/openerp/addons/hw_screen/controllers/main.py
COPY hw_printer_network_controller.py /opt/posbox/addons/hw_printer_network/controllers/hw_printer_network_controller.py
# Set default user when running the container
USER odoo

View File

@ -0,0 +1,209 @@
# Copyright 2017-2018 Dinar Gabbasov <https://it-projects.info/team/GabbasovDinar>
# Copyright 2018 Tom Blauwendraat <tom@sunflowerweb.nl>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from openerp import http
import logging
import time
import socket
import subprocess
import threading
import traceback
_logger = logging.getLogger(__name__)
try:
from openerp.addons.hw_escpos.escpos import escpos
from openerp.addons.hw_escpos.controllers.main import EscposProxy
from openerp.addons.hw_escpos.controllers.main import EscposDriver
from openerp.addons.hw_escpos.escpos.printer import Network
import openerp.addons.hw_proxy.controllers.main as hw_proxy
except ImportError:
EscposProxy = object
EscposDriver = object
class PingProcess(threading.Thread):
def __init__(self, ip):
self.stdout = None
self.stderr = None
threading.Thread.__init__(self)
self.status = 'offline'
self.ip = ip
self.stop = False
def run(self):
while not self.stop:
child = subprocess.Popen(
["ping", "-c1", "-w5", self.ip],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
child.communicate()
self.status = 'offline' if child.returncode else 'online'
time.sleep(1)
def get_status(self):
return self.status
def __del__(self):
self.stop = True
class EscposNetworkDriver(EscposDriver):
def __init__(self):
self.network_printers = []
self.ping_processes = {}
self.printer_objects = {}
super(EscposNetworkDriver, self).__init__()
def get_network_printer(self, ip, name=None):
found_printer = False
for printer in self.network_printers:
if printer['ip'] == ip:
found_printer = True
if name:
printer['name'] = name
if printer['status'] == 'online':
printer_object = self.printer_objects.get(ip, None)
if not printer_object:
try:
printer_object = Network(ip)
self.printer_objects[ip] = printer_object
except socket.error:
pass
return printer
if not found_printer:
self.add_network_printer(ip, name)
return None
def add_network_printer(self, ip, name=None):
printer = dict(
ip=ip,
status='offline',
name=name or 'Unnamed printer'
)
self.network_printers.append(printer) # dont return because offline
self.start_pinging(ip)
def start_pinging(self, ip):
pinger = PingProcess(ip)
self.ping_processes[ip] = pinger
pinger.start()
def update_driver_status(self):
count = len([p for p in self.network_printers if p.get('status', None) == 'online'])
if count:
self.set_status('connected', '{} printer(s) Connected'.format(count))
else:
self.set_status('disconnected', 'Disconnected')
def run(self):
if not escpos:
_logger.error('ESC/POS cannot initialize, please verify system dependencies.')
return
while True:
try:
error = True
timestamp, task, data = self.queue.get(True)
if task == 'xml_receipt':
error = False
if timestamp >= (time.time() - 1 * 60 * 60):
receipt, network_printer_ip = data
printer_info = self.get_network_printer(network_printer_ip)
printer = self.printer_objects.get(network_printer_ip, None)
if printer_info and printer_info['status'] == 'online' and printer:
_logger.info('Printing XML receipt on printer %s...', network_printer_ip)
try:
printer.receipt(receipt)
except socket.error:
printer.open()
printer.receipt(receipt)
_logger.info('Done printing XML receipt on printer %s', network_printer_ip)
else:
_logger.error('xml_receipt: printer offline!')
# add a missed order to queue
time.sleep(3)
self.queue.put((timestamp, task, data))
elif task == 'cashbox':
printer_info = self.get_network_printer(data)
printer = self.printer_objects.get(data, None)
if printer_info and printer_info['status'] == 'online' and printer:
_logger.info('Opening cashbox on printer %s...', data)
try:
printer.cashdraw(2)
printer.cashdraw(5)
except socket.error:
printer.open()
printer.cashdraw(2)
printer.cashdraw(5)
_logger.info('Done opening cashbox on printer %s', data)
else:
_logger.error('cashbox: printer offline!')
elif task == 'printstatus':
pass
elif task == 'status':
error = False
for printer in self.network_printers:
ip = printer['ip']
pinger = self.ping_processes.get(ip, None)
if pinger and pinger.isAlive():
status = pinger.get_status()
if status != printer['status']:
# todo: use a lock?
printer['status'] = status
self.update_driver_status()
else:
self.start_pinging(ip)
error = False
except Exception as e:
self.set_status('error', str(e))
errmsg = str(e) + '\n' + '-'*60+'\n' + traceback.format_exc() + '-'*60 + '\n'
_logger.error(errmsg)
finally:
if error:
self.queue.put((timestamp, task, data))
# Separate instance, mainloop and queue for network printers
# original driver runs in parallel and deals with USB printers
network_driver = EscposNetworkDriver()
hw_proxy.drivers['escpos_network'] = network_driver
# this will also start the message handling loop
network_driver.push_task('printstatus')
class UpdatedEscposProxy(EscposProxy):
@http.route('/hw_proxy/print_xml_receipt', type='json', auth='none', cors='*')
def print_xml_receipt(self, receipt, proxy=None):
if proxy:
_logger.info('print_xml_receipt proxy %s', proxy)
network_driver.push_task('xml_receipt', (receipt, proxy))
else:
super(UpdatedEscposProxy, self).print_xml_receipt(receipt)
@http.route('/hw_proxy/open_cashbox', type='json', auth='none', cors='*')
def open_cashbox(self, proxy=None):
_logger.info('Open cashbox via network printer')
network_driver.push_task('cashbox', '192.168.233.3')
@http.route('/hw_proxy/network_printers', type='json', auth='none', cors='*')
def network_printers(self, network_printers=None):
for printer in network_printers:
network_driver.get_network_printer(printer['ip'], name=printer['name'])
@http.route('/hw_proxy/status_network_printers', type='json', auth='none', cors='*')
def network_printers_status(self):
return network_driver.network_printers
@http.route('/hw_proxy/without_usb', type='http', auth='none', cors='*')
def without_usb(self):
""" Old pos_printer_network module expects this to work """
return "ping"