def update(self): """Get the latest data from the remote SNMP capable host.""" from pysnmp.hlapi import (getCmd, CommunityData, SnmpEngine, UdpTransportTarget, ContextData, ObjectType, ObjectIdentity) from brother_ql.reader import interpret_response errindication, errstatus, errindex, restable = next( getCmd(SnmpEngine(), CommunityData(self._community, mpModel=0), UdpTransportTarget((self._host, self._port)), ContextData(), ObjectType(ObjectIdentity(self._baseoid)))) if errindication: _LOGGER.error("SNMP error: %s", errindication) elif errstatus: _LOGGER.error("SNMP error: %s at %s", errstatus.prettyPrint(), errindex and restable[-1][int(errindex) - 1] or '?') else: assert len(restable) == 1 status = interpret_response(bytes(restable[0][1])) self.media_type = status['media_type'] self.media_width = '{} mm'.format(status['media_width']) self.media_length = status['media_length'] or 'endless' self.phase = status['phase_type'] self.errors = ', '.join(status['errors']) or '-none-' if status['errors']: self.state = 'error' elif 'waiting' in status['phase_type'].lower(): self.state = 'idle' elif 'printing' in status['phase_type'].lower(): self.state = 'printing' else: self.state = STATE_UNKNOWN
def log_interp_response(self, data): try: interp_result = interpret_response(data) logger.info( "Interpretation of the response: '{status_type}' (phase: {phase_type}), '{media_type}' {media_width}x{media_length} mm^2, errors: {errors}" .format(**interp_result)) except: logger.error("Couln't interpret response: %s", hex_format(data))
def send(instructions, printer_identifier=None, backend_identifier=None, blocking=True): """ Send instruction bytes to a printer. :param bytes instructions: The instructions to be sent to the printer. :param str printer_identifier: Identifier for the printer. :param str backend_identifier: Can enforce the use of a specific backend. :param bool blocking: Indicates whether the function call should block while waiting for the completion of the printing. """ status = { 'instructions_sent': True, # The instructions were sent to the printer. 'outcome': 'unknown', # String description of the outcome of the sending operation like: 'unknown', 'sent', 'printed', 'error' 'printer_state': None, # If the selected backend supports reading back the printer state, this key will contain it. 'did_print': False, # If True, a print was produced. It defaults to False if the outcome is uncertain (due to a backend without read-back capability). 'ready_for_next_job': False, # If True, the printer is ready to receive the next instructions. It defaults to False if the state is unknown. } selected_backend = None if backend_identifier: selected_backend = backend_identifier else: try: selected_backend = guess_backend(printer_identifier) except: logger.info( "No backend stated. Selecting the default linux_kernel backend." ) selected_backend = 'linux_kernel' be = backend_factory(selected_backend) list_available_devices = be['list_available_devices'] BrotherQLBackend = be['backend_class'] printer = BrotherQLBackend(printer_identifier) start = time.time() logger.info('Sending instructions to the printer. Total: %d bytes.', len(instructions)) printer.write(instructions) status['outcome'] = 'sent' if not blocking: return status if selected_backend == 'network': """ No need to wait for completion. The network backend doesn't support readback. """ return status while time.time() - start < 10: data = printer.read() if not data: time.sleep(0.005) continue try: result = interpret_response(data) except ValueError: logger.error("TIME %.3f - Couln't understand response: %s", time.time() - start, data) continue status['printer_state'] = result logger.debug('TIME %.3f - result: %s', time.time() - start, result) if result['errors']: logger.error('Errors occured: %s', result['errors']) status['outcome'] = 'error' break if result['status_type'] == 'Printing completed': status['did_print'] = True status['outcome'] = 'printed' if result['status_type'] == 'Phase change' and result[ 'phase_type'] == 'Waiting to receive': status['ready_for_next_job'] = True if status['did_print'] and status['ready_for_next_job']: break if not status['did_print']: logger.warning("'printing completed' status not received.") if not status['ready_for_next_job']: logger.warning("'waiting to receive' status not received.") if (not status['did_print']) or (not status['ready_for_next_job']): logger.warning('Printing potentially not successful?') if status['did_print'] and status['ready_for_next_job']: logger.info("Printing was successful. Waiting for the next job.") return status
def main(): parser = argparse.ArgumentParser() parser.add_argument("--backend", choices=available_backends, help="Forces the use of a specific backend") parser.add_argument( "--list-printers", action="store_true", help="List the devices available with the selected --backend" ) parser.add_argument("--debug", action="store_true", help="Enable debugging output") parser.add_argument( "instruction_file", nargs="?", help="file containing the instructions to be sent to the printer" ) parser.add_argument( "device", metavar="DEVICE_STRING_DESCRIPTOR", nargs="?", help="String descriptor for specific device. If not specified, select first detected device", ) args = parser.parse_args() if args.list_printers and not args.backend: parser.error("Please specify the backend in order to list available devices.") if not args.list_printers and not args.instruction_file: parser.error("the following arguments are required: instruction_file") level = logging.DEBUG if args.debug else logging.WARNING logging.basicConfig(level=level) if args.backend == "network": logger.warning( "The network backend doesn't supply any 'readback' functionality. No status reports will be received." ) selected_backend = None if args.backend: selected_backend = args.backend else: try: selected_backend = guess_backend(args.device) except: logger.info("No backend stated. Selecting the default linux_kernel backend.") selected_backend = "linux_kernel" be = backend_factory(selected_backend) list_available_devices = be["list_available_devices"] BrotherQLBackend = be["backend_class"] if args.list_printers: for printer in list_available_devices(): print(printer["string_descr"]) sys.exit(0) string_descr = None if not args.device: "We need to search for available devices and select the first." ad = list_available_devices() if not ad: sys.exit("No printer found") string_descr = ad[0]["string_descr"] print("Selecting first device %s" % string_descr) else: "A string descriptor for the device was given, let's use it." string_descr = args.device printer = BrotherQLBackend(string_descr) start = time.time() with open(args.instruction_file, "rb") as f: content = f.read() logger.info("Sending instructions to the printer. Total: %d bytes.", len(content)) printer.write(content) if selected_backend == "network": """ No need to wait for completion. The network backend doesn't support readback. """ return printing_completed = False waiting_to_receive = False while time.time() - start < 10: data = printer.read() if not data: time.sleep(0.005) continue try: result = interpret_response(data) except ValueError: logger.error("TIME %.3f - Couln't understand response: %s", time.time() - start, data) continue logger.debug("TIME %.3f - result: %s", time.time() - start, result) if result["errors"]: logger.error("Errors occured: %s", result["errors"]) if result["status_type"] == "Printing completed": printing_completed = True if result["status_type"] == "Phase change" and result["phase_type"] == "Waiting to receive": waiting_to_receive = True if printing_completed and waiting_to_receive: break if not (printing_completed and waiting_to_receive): logger.warning("Printing potentially not successful?")
def send(instructions, printer_identifier=None, backend_identifier=None, blocking=True): """ Send instruction bytes to a printer. :param bytes instructions: The instructions to be sent to the printer. :param str printer_identifier: Identifier for the printer. :param str backend_identifier: Can enforce the use of a specific backend. :param bool blocking: Indicates whether the function call should block while waiting for the completion of the printing. """ selected_backend = None if backend_identifier: selected_backend = backend_identifier else: try: selected_backend = guess_backend(printer_identifier) except: logger.info("No backend stated. Selecting the default linux_kernel backend.") selected_backend = 'linux_kernel' be = backend_factory(selected_backend) list_available_devices = be['list_available_devices'] BrotherQLBackend = be['backend_class'] printer = BrotherQLBackend(printer_identifier) start = time.time() logger.info('Sending instructions to the printer. Total: %d bytes.', len(instructions)) printer.write(instructions) if not blocking: return if selected_backend == 'network': """ No need to wait for completion. The network backend doesn't support readback. """ return printing_completed = False waiting_to_receive = False while time.time() - start < 10: data = printer.read() if not data: time.sleep(0.005) continue try: result = interpret_response(data) except ValueError: logger.error("TIME %.3f - Couln't understand response: %s", time.time()-start, data) continue logger.debug('TIME %.3f - result: %s', time.time()-start, result) if result['errors']: logger.error('Errors occured: %s', result['errors']) if result['status_type'] == 'Printing completed': printing_completed = True if result['status_type'] == 'Phase change' and result['phase_type'] == 'Waiting to receive': waiting_to_receive = True if printing_completed and waiting_to_receive: break if not printing_completed: logger.warning("'printing completed' status not received.") if not waiting_to_receive: logger.warning("'waiting to receive' status not received.") if (not printing_completed) or (not waiting_to_receive): logger.warning('Printing potentially not successful?') if printing_completed and waiting_to_receive: logger.info("Printing was successful. Waiting for the next job.")
def main(): parser = argparse.ArgumentParser() parser.add_argument('--backend', choices=available_backends, help='Forces the use of a specific backend') parser.add_argument( '--list-printers', action='store_true', help='List the devices available with the selected --backend') parser.add_argument('--debug', action='store_true', help='Enable debugging output') parser.add_argument( 'instruction_file', nargs='?', help='file containing the instructions to be sent to the printer') parser.add_argument( 'device', metavar='DEVICE_STRING_DESCRIPTOR', nargs='?', help= 'String descriptor for specific device. If not specified, select first detected device' ) args = parser.parse_args() if args.list_printers and not args.backend: parser.error( 'Please specify the backend in order to list available devices.') if not args.list_printers and not args.instruction_file: parser.error("the following arguments are required: instruction_file") if args.instruction_file == '-': try: content = sys.stdin.buffer.read() except AttributeError: content = sys.stdin.read() else: with open(args.instruction_file, 'rb') as f: content = f.read() level = logging.DEBUG if args.debug else logging.WARNING logging.basicConfig(level=level) if args.backend == 'network': logger.warning( "The network backend doesn't supply any 'readback' functionality. No status reports will be received." ) selected_backend = None if args.backend: selected_backend = args.backend else: try: selected_backend = guess_backend(args.device) except: logger.info( "No backend stated. Selecting the default linux_kernel backend." ) selected_backend = 'linux_kernel' be = backend_factory(selected_backend) list_available_devices = be['list_available_devices'] BrotherQLBackend = be['backend_class'] if args.list_printers: for printer in list_available_devices(): print(printer['string_descr']) sys.exit(0) string_descr = None if not args.device: "We need to search for available devices and select the first." ad = list_available_devices() if not ad: sys.exit("No printer found") string_descr = ad[0]['string_descr'] print("Selecting first device %s" % string_descr) else: "A string descriptor for the device was given, let's use it." string_descr = args.device printer = BrotherQLBackend(string_descr) start = time.time() logger.info('Sending instructions to the printer. Total: %d bytes.', len(content)) printer.write(content) if selected_backend == 'network': """ No need to wait for completion. The network backend doesn't support readback. """ return printing_completed = False waiting_to_receive = False while time.time() - start < 10: data = printer.read() if not data: time.sleep(0.005) continue try: result = interpret_response(data) except ValueError: logger.error("TIME %.3f - Couln't understand response: %s", time.time() - start, data) continue logger.debug('TIME %.3f - result: %s', time.time() - start, result) if result['errors']: logger.error('Errors occured: %s', result['errors']) if result['status_type'] == 'Printing completed': printing_completed = True if result['status_type'] == 'Phase change' and result[ 'phase_type'] == 'Waiting to receive': waiting_to_receive = True if printing_completed and waiting_to_receive: break if not (printing_completed and waiting_to_receive): logger.warning('Printing potentially not successful?')
def log_interp_response(self, data): try: interp_result = interpret_response(data) logger.info("Interpretation of the response: '{status_type}' (phase: {phase_type}), '{media_type}' {media_width}x{media_length} mm^2, errors: {errors}".format(**interp_result)) except: logger.error("Couln't interpret response: %s", hex_format(data))